最近,因为工作关系,涉及到需要从零开始搭建一套应用系统开发框架。系统权限管控这块,我选择了shiro来实现。因为服务端集成框架已经确定使用springboot1.5,所以就需要将shiro进行整合。
首先,先介绍下项目技术栈如下:
前端:bootstrap3、jquery1.10
服务端:jdk8、springboot1.5、springmvc4.3、mybatis1.2、log4j2
IDE:idea 201704
然后,开始springboot整合shiro操作步骤:
1、Maven POM配置文件中,增加如下shiro依赖配置,如下所示:
PS:这里选择了starter方式,也可以采用以前的非starter方式整合。
2、实现shiro核心集成步骤
集成shiro最关键的是实现三个步骤,1是实现自己的Realm,2是实现ShiroConfiguration,3是结合Subject实现登录Controller
以下是我实现的以上三步的具体代码:
1)AuthRealm:自己实现的Realm
public class AuthRealm extends AuthorizingRealm {
@Autowired
private LoginService loginService;
@Resource
private CacheManager cacheManager;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SpUserInfoDO userInfo = (SpUserInfoDO)principalCollection.fromRealm(getName()).iterator().next();
if(userInfo!=null){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole(userInfo.getRoleInfo().getRoleId());
return info;
}
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (authenticationToken.getPrincipal() == null) {
return null;
}
//获取用户信息
String userName = authenticationToken.getPrincipal().toString();
List<SpUserInfoDO> userList = loginService.queryUserAndRoleById(userName);
SpUserInfoDO userInfo = null;
if(userList==null||userList.size()==0){
return null;
}else{
for(SpUserInfoDO spUserInfoDO:userList){
userInfo = spUserInfoDO;
userInfo.setShowRoleName(userInfo.getRoleInfo().getRoleName());
}
}
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userInfo, userInfo.getPasswd(), getName());
return simpleAuthenticationInfo;
}
}
2)ShiroConfiguration
public class ShiroConfiguration {
@Bean
public AuthRealm authRealm() {
AuthRealm authRealm = new AuthRealm();
return authRealm;
}
//权限管理,配置主要是Realm的管理认证
@Bean
public SessionsSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(authRealm());
return securityManager;
}
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SessionsSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> map = new HashMap<String, String>();
//登出
map.put("/svnplus/logout","logout");
//跳过认证的资源
map.put("/css/**","anon");
map.put("/js/**","anon");
map.put("/img/**","anon");
map.put("/h2-console/**","anon");
map.put("/checkLogin/**","anon");
map.put("/logout/**","anon");
//对所有用户认证
map.put("/**","authc");
//登录
shiroFilterFactoryBean.setLoginUrl("/svnplus/login");
//首页
shiroFilterFactoryBean.setSuccessUrl("/wfcontrol/index");
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/svnplus/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean(name = "sessionManager")
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
// 设置session过期时间1200s
sessionManager.setGlobalSessionTimeout(1200000L);
return sessionManager;
}
}
3)LoginController:登录控制器
public class LoginController {
public final static Logger logger = LoggerFactory.getLogger(LoginController.class);
@RequestMapping(value = {"/", "/login", "/svnplus/login"}, method = RequestMethod.GET)
public String login(Model model){
if (SecurityUtils.getSubject().isAuthenticated()) {
return "redirect:/wfcontrol/index";
} else {
return "login";
}
}
@RequestMapping(value = {"/checkLogin","/svnplus/checkLogin"})
public String checkLogin(Model model,HttpServletRequest request, String username, String password){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
SpUserInfoDO userInfo = (SpUserInfoDO) subject.getPrincipal();
HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
HttpSession session = httpServletRequest.getSession();
session.setAttribute("UserRoleId", userInfo.getRoleInfo().getRoleId());
} catch (UnknownAccountException e) {
model.addAttribute("msg","用户名不存在!");
return "login";
} catch (IncorrectCredentialsException e) {
model.addAttribute("msg","用户或密码错误!");
return "login";
} catch (AuthenticationException e) {
model.addAttribute("msg","登录验证未通过!");
return "login";
}
return "index";
}
@RequestMapping(value = {"/logout","/svnplus/logout"}, method = RequestMethod.GET)
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
}
}
实现了以上3个组成部分,就可以启动并测试整合后的权限控制了。
以上只是实现最基本整合的过程。