- 自定义Realm
@Component
public class Oauth2Realm extends AuthorizingRealm {
@Autowired
private ShiroService shiroService;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof Oauth2Token;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
UserDetail user = (UserDetail)principals.getPrimaryPrincipal();
Set<String> permsSet = shiroService.getUserPermissions(user);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String accessToken = (String) token.getPrincipal();
SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken);
if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){
throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID));
}
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
if(userDetail.getStatus() == 0){
throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK));
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDetail, accessToken, getName());
return info;
}
}
2. 创建配置类
@Configuration
public class ShiroConfig {
@Bean
public DefaultWebSessionManager sessionManager(){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionValidationSchedulerEnabled(false);
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
@Bean("securityManager")
public SecurityManager securityManager(SessionManager sessionManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
List<Realm> list = new ArrayList<>();
list.add(getOauth2Realm());
securityManager.setRealms(list);
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(null);
return securityManager;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
Map<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new Oauth2Filter());
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
filterMap.put("login", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/doc.html", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/captcha", "anon");
filterMap.put("/favicon.ico", "anon");
filterMap.put("/", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
@Bean("lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
public Realm getOauth2Realm(){
Oauth2Realm realm = new Oauth2Realm();
realm.setCacheManager(new RedisCacheManager());
realm.setCachingEnabled(true);
realm.setAuthenticationCachingEnabled(true);
realm.setAuthenticationCacheName("consoleAuthenticationCache");
realm.setAuthorizationCachingEnabled(true);
realm.setAuthorizationCacheName("consoleAuthorizationCache");
return realm;
}
}
3. 常见过滤器
| 配置缩写 | 对应的过滤器 | 功能 |
|---|
| anon | AnonymousFilter | 指定url可以匿名访问 |
| authc | FormAuthenticationFilter | 指定url需要form表单登录,默认会从请求中获取username、password,rememberMe等参数并尝试登录,如果登录不了就会跳转到loginUrl配置的路径。我们也可以用这个过滤器做默认的登录逻辑,但是一般都是我们自己在控制器写登录逻辑的,自己写的话出错返回的信息都可以定制嘛。 |
| authcBasic | BasicHttpAuthenticationFilter | 指定url需要basic登录 |
| logout | LogoutFilter | 登出过滤器,配置指定url就可以实现退出功能,非常方便 |
| noSessionCreation | NoSessionCreationFilter | 禁止创建会话 |
| perms | PermissionsAuthorizationFilter | 需要指定权限才能访问 |
| port | PortFilter | 需要指定端口才能访问 |
| rest | HttpMethodPermissionFilter | 将http请求方法转化成相应的动词来构造一个权限字符串,这个感觉意义不大,有兴趣自己看源码的注释 |
| roles | RolesAuthorizationFilter | 需要指定角色才能访问 |
| ssl | SslFilter | 需要https请求才能访问 |
| user | UserFilter | 需要已登录或“记住我”的用户才能访问 |