1.添加shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
2.自定义 Shiro 过滤器
(Realm,开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部写在 Realm 中。)
public class AccoutRealm extends AuthorizingRealm {
@Autowired
private AccountService accountService;
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
Account account = accountService.findByUsername(token.getUsername());
if(account != null){
return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
}
return null;
}
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
3.添加配置类,让realm起作用。即注入到IOC中
@Configuration
public class ShiroConfig {
private static final String SHIRO_DIALECT = "shiroDialect";
private static final String SHIRO_FILTER = "shiroFilter";
private String hashAlgorithmName = "md5";// 加密方式
private int hashIterations = 2;// 散列次数
private String loginUrl = "/index.html";// 默认的登陆页面
private String[] anonUrls;
private String logOutUrl;
private String[] authcUlrs;
/**
* 声明userRealm
* //创建realm对象,需要自定义类 (第一步:创建realm对象)
* @Bean(name="userRealm") //@Bean注解后便被spring托管,不加name属性,默认name值为方法名,这里就加一下吧
*/
@Bean("userRealm")
public UserRealm userRealm(CredentialsMatcher credentialsMatcher) {
UserRealm userRealm = new UserRealm();
// 注入凭证匹配器
userRealm.setCredentialsMatcher(credentialsMatcher);
return userRealm;
}
/**
* 配置SecurityManager //DefaultWebSecurityManager (第二步:管理realm对象)
*/
@Bean("securityManager")
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 注入userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 配置shiro的过滤器
*
//ShiroFilterFactoryBean (第三步:连接到前端)
*/
@Bean(SHIRO_FILTER)
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// 设置安全管理器
factoryBean.setSecurityManager(securityManager);
// 设置未登陆的时要跳转的页面
factoryBean.setLoginUrl(loginUrl);
Map<String, String> filterChainDefinitionMap = new HashMap<>();
// 设置放行的路径
if (anonUrls != null && anonUrls.length > 0) {
for (String anon : anonUrls) {
//anon:无需认证。
filterChainDefinitionMap.put(anon, "anon");
}
}
// 设置登出的路径
if (null != logOutUrl) {
filterChainDefinitionMap.put(logOutUrl, "logout");
}
// 设置拦截的路径
if (authcUlrs != null && authcUlrs.length > 0) {
for (String authc : authcUlrs) {
//authc:必须认证。
filterChainDefinitionMap.put(authc, "authc");
}
}
Map<String, Filter> filters=new HashMap<>();
// filters.put("authc", new ShiroLoginFilter());
//配置过滤器L
factoryBean.setFilters(filters);
//设置过滤器链的集合
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
}
3.1备注
编写认证和授权规则:
** 认证过滤器
anon:无需认证。
authc:必须认证。
authcBasic:需要通过 HTTPBasic 认证。
user:不一定通过认证,只要曾经被 Shiro 记录即可,比如:记住我。
** 授权过滤器
perms:必须拥有某个权限才能访问。
role:必须拥有某个角色才能访问。
port:请求的端口必须是指定值才可以。
rest:请求必须基于 RESTful,POST、PUT、GET、DELETE。
ssl:必须是安全的 URL 请求,协议 HTTPS。
4.controller
@RequestMapping("login")
public ResultObj login(String loginname,String pwd) {
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token=new UsernamePasswordToken(loginname, pwd);
try {
subject.login(token);
ActiverUser activerUser=(ActiverUser) subject.getPrincipal();
WebUtils.getSession().setAttribute("user", activerUser.getUser());
return ResultObj.LOGIN_SUCCESS;
} catch (AuthenticationException e) {
e.printStackTrace();
return ResultObj.LOGIN_ERROR_PASS;
}
}