|
shiro官网:http://shiro.apache.org/
项目结构

单点登录地址配置
biz.properties
biz.ldapUrl=***-ad-01.ymt.corp
springboot加载
Application.java

配置
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class BizConfig {
@Value("${biz.ldapUrl}")
private String ldapUrl;
@Value("${stress.clientIp}")
private String stressIp;
@Value("${sit.clientIp}")
private String sitIp;
@Value("${uat.clientIp}")
private String uatIp;
@Value("${clientport}")
private String clientPort;
@Value("${isEnableSend}")
private boolean isEnableSend;
@Value("${alarm.cron}")
private String alarmcron;
public String getLdapUrl() {
return ldapUrl;
}
public void setLdapUrl(String ldapUrl) {
this.ldapUrl = ldapUrl;
}
public String getStressIp() {
return stressIp;
}
public void setStressIp(String stressIp) {
this.stressIp = stressIp;
}
public String getSitIp() {
return sitIp;
}
public void setSitIp(String sitIp) {
this.sitIp = sitIp;
}
public String getUatIp() {
return uatIp;
}
public void setUatIp(String uatIp) {
this.uatIp = uatIp;
}
public String getClientPort() {
return clientPort;
}
public void setClientPort(String clientPort) {
this.clientPort = clientPort;
}
public boolean isEnableSend() {
return isEnableSend;
}
public void setEnableSend(boolean enableSend) {
isEnableSend = enableSend;
}
public String getAlarmcron() {
return alarmcron;
}
public void setAlarmcron(String alarmcron) {
this.alarmcron = alarmcron;
}
}
import com.ymatou.envmanagement.shiro.AdminAuthorizationFilter;
import com.ymatou.envmanagement.shiro.MyAuthorizingRealm;
import com.ymatou.envmanagement.shiro.SecurityFilterChainDefinitionSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
private static Log logger = LogFactory.getLog(ShiroConfig.class);
@Bean
public ShiroFilterFactoryBean shiroFilter() throws Exception {
Map<String, Filter> filters = new HashMap<String, Filter>();
filters.put("admin", new AdminAuthorizationFilter());
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean.setSecurityManager(securityManager());
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionSource().getObject());
return shiroFilterFactoryBean;
}
@Bean(name = "securityManager")
public org.apache.shiro.mgt.SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm());
return securityManager;
}
@Bean
public AuthorizingRealm myRealm() {
return new MyAuthorizingRealm();
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public SecurityFilterChainDefinitionSource filterChainDefinitionSource() {
return new SecurityFilterChainDefinitionSource();
}
定制代码
import com.ymatou.envmanagement.model.User;
import com.ymatou.envmanagement.util.CurrentUserUtil;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class AdminAuthorizationFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
User user = CurrentUserUtil.getCurrentUser();
if(user != null){
return true;
}
return false;
}
}
import com.ymatou.envmanagement.config.BizConfig;
import com.ymatou.envmanagement.exception.BaseRunTimeException;
import com.ymatou.envmanagement.util.LdapHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
public class MyAuthorizingRealm extends AuthorizingRealm {
private static Log logger = LogFactory.getLog(MyAuthorizingRealm.class);
@Autowired
private BizConfig bizConfig;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken authcToken = (UsernamePasswordToken) token;
String userName = authcToken.getUsername();
String password = String.valueOf(authcToken.getPassword());
logger.info("login userName: " + userName);
String ldapUrl = bizConfig.getLdapUrl();
if (LdapHelper.authenticate(userName, password, ldapUrl)) {
return new SimpleAuthenticationInfo(userName, password, getName());
} else {
if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(password)) {
// password = CipherUtil.encryptMD5(password);
// User user = userService.getUser(userName, password);
//
// /**
// * 重新放入,防止 shiro报错org.apache.shiro.authc.IncorrectCredentialsException:
// * Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=true]
// * did not match the expected credentials.
// */
// authcToken.setPassword(password.toCharArray());
// if(user != null){
// return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
// }else {
// throw new BaseRunTimeException("用户名或密码错误");
// }
throw new BaseRunTimeException(String.format("Authenticate Failed. UserName: %s", userName));
}
}
return null;
}
}
import org.apache.shiro.config.Ini;
import org.apache.shiro.web.config.IniFilterChainResolverFactory;
import org.springframework.beans.factory.FactoryBean;
public class SecurityFilterChainDefinitionSource implements FactoryBean<Ini.Section> {
@Override
public Ini.Section getObject() throws Exception {
return loadSection();
}
@Override
public Class<?> getObjectType() {
return this.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
private Ini.Section loadSection() {
Ini ini = Ini.fromResourcePath("classpath:shiro.ini");
Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);
return section;
}
}
使用示例
import com.ymatou.envmanagement.model.User;
import com.ymatou.envmanagement.util.SessionUtil;
import com.ymatou.envmanagement.util.WapperUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("")
public class LoginController {
private final static Logger logger = LoggerFactory.getLogger(LoginController.class);
@RequestMapping("/auth")
public Object auth(String username, String password) {
String errorMessage = "未知错误!";
if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
// 得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject currentUser = SecurityUtils.getSubject();
// 如果用户已经登录
if (currentUser.isAuthenticated()) {
return WapperUtil.success("该用户已经登录!");
}
if(username.equals("admin") && password.equals("admin"))
{
// 获取已认证用户User
User user = new User();
user.setUsername(username);
user.setPassword(password);
// 增加用户的相关数据进入Session
addUserInfoToSession(user);
return WapperUtil.success("登录成功");
}
// 登录Token验证
UsernamePasswordToken token = new UsernamePasswordToken(username, password, true);
try {
currentUser.login(token);
// 判断用户是否已经认证
if (currentUser.isAuthenticated()) {
// 获取已认证用户User
User user = new User();
user.setUsername(username);
user.setPassword(password);
// 增加用户的相关数据进入Session
addUserInfoToSession(user);
return WapperUtil.success("登录成功");
}
} catch (AuthenticationException e) { // 登录失败
errorMessage = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
logger.info("登录失败", e);
} catch (Exception e) {
errorMessage = "未知错误!";
logger.info("登录失败", e);
}
} else {
errorMessage = "用户名或密码为空!";
}
return WapperUtil.error(errorMessage);
}
/**
* 增加用户的信息到session中
*/
private void addUserInfoToSession(User user) {
// 设置用户的信息到session中
SessionUtil.put(SessionUtil.SESSION_KEY_USER_ID, user.getUsername());
SessionUtil.put(SessionUtil.SESSION_KEY_USER, user);
}
@RequestMapping("/logout")
public Object logout() {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
subject.logout();
return WapperUtil.success();
}
return WapperUtil.error("您还未登录!");
}
@RequestMapping("/version")
public String version() {
return "2017-03-09-1";
}
@RequestMapping("/warmup")
public String status() {
return "ok";
}
}
具体原理参考:http://blog.csdn.net/catoop/article/details/50520958
|