SpringBoot集成shiro做登录认证和权限管理
shiro就不过多解释了,可以看官网文档了解shiro的用处。
本文采用SpringBoot,持久层mybatis,数据库pg来集成shiro。
直接上代码
- shiro依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.7.0</version>
</dependency>
- ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/doc.html", "anon"); //swagger
filterChainDefinitionMap.put("/swagger-resources", "anon");
filterChainDefinitionMap.put("/v2/api-docs", "anon");
filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/*", "authc");
shiroFilterFactoryBean.setLoginUrl("/tologin"); //未登录跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); //无权限跳转
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//SecurityManager
@Bean(name = "securityManager")
public SecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm); //将Realm注入到SecurityManager中。
securityManager.setRememberMeManager(cookieRememberMeManager()); //注入rememberMeManager;
return securityManager;
}
@Bean(name = "userRealm")
public UserRealm userRealm() {
UserRealm myShiroRealm = new UserRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); //设置解密规则
return myShiroRealm;
}
//解密
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//md5
hashedCredentialsMatcher.setHashIterations(2);// 加密2次 md5(md5(""));
return hashedCredentialsMatcher;
}
- 自定义Realm
public class UserRealm extends AuthorizingRealm {
@Autowired
private LoginService loginService;
@Autowired
private RoleMapper roleMapper;
@Autowired
private PermissionMapper permissionMapper;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
System.out.println("授权-->UserRealm.doGetAuthorizationInfo()");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User userInfo = (User) principal.getPrimaryPrincipal();
List<Role> roles = roleMapper.findRoleByUsername(userInfo.getUsername());
if (roles != null) {
roles.stream().forEach(
role -> {
authorizationInfo.addRole(role.getRoleName());
permissionMapper.findPermissionByRoleId(role.getRoleId()).stream().forEach(
permission -> {
authorizationInfo.addStringPermission(permission.getPermCode());
}
);
});
}
return authorizationInfo;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证-->UserRealm.doGetAuthenticationInfo()");
//获取username
String username = (String) token.getPrincipal();
System.out.println(token.getCredentials());
//根据username获取用户信息
User user = loginService.findByUsername(username);
if (user == null) {
//UnknownAccountException
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user, //用户信息
user.getPassword(), //密码
ByteSource.Util.bytes(user.getSalt()),//salt
getName() //realm name
);
return authenticationInfo;
}
- Controller
public ResultEntry<ReturnCode> login(String username, String password) {
//登录认证
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
} catch (IncorrectCredentialsException e) { //用户密码错误
return new ResultEntry<>(ReturnCode.USERNAME_PASSWORD_ERROR.getCode(), ReturnCode.USERNAME_PASSWORD_ERROR.getMsg());
} catch (AuthenticationException e) { //其他错误
return new ResultEntry<>(ReturnCode.FAIL.getCode(), ReturnCode.FAIL.getMsg());
}
return new ResultEntry().setResult(vo);
}
后续详细更新…