Shiro安全框架案例
配置
依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
拦截配置
创建config类
package com.cy.pj.common.config;
/**@Configuration 注解描述的类为一个配置对象,
* 此对象也会交给spring管理
*/
@Configuration
public class SpringShiroConfig {//spring-shiro.xml
}
添加SecurityManager配置类
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager sManager=
new DefaultWebSecurityManager();
return sManager;
}
添加ShiroFilterFactoryBean对象的配置
@Bean
public ShiroFilterFactoryBean shiroFilterFactory (
SecurityManager securityManager) {
ShiroFilterFactoryBean sfBean=
new ShiroFilterFactoryBean();
sfBean.setSecurityManager(securityManager);
sfBean.setLoginUrl("/homework/dologin");
//定义map指定请求过滤规则(哪些资源允许匿名访问,哪些必须认证访问)
LinkedHashMap<String,String> map= new LinkedHashMap<>();
//静态资源允许匿名访问:"anon"
map.put("/css/**","anon");
map.put("/img/**","anon");
map.put("/js/**","anon");
map.put("/homework/doupdate","anon");
map.put("/homework/doregister","anon");
//map.put("/doLogout","logout"); //退出操作
//除了匿名访问的资源,其它都要认证("authc")后访问
map.put("/**","authc");
//配置认证管理器
sfBean.setFilterChainDefinitionMap(map);
return sfBean;
}
认证配置
认证流程
- 系统调用subject的login方法将用户信息提交给SecurityManager
- SecurityManager将认证操作委托给认证器对象Authenticator
- Authenticator将用户输入的身份信息传递给Realm。
- Realm访问数据库获取用户信息然后对信息进行封装并返回。
- Authenticator 对realm返回的信息进行身份认证。
DAO层根据情况(简略)
HomeworkEntity findUserByUserName(String username)。
Realm继承AuthorizingRealm–完成认证(授权暂时没写)
@Component
public class UserRealm extends AuthorizingRealm{
@Resource
private HomeWorkDao homeWorkDao;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("授权操作");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证操作");
UsernamePasswordToken token2 = (UsernamePasswordToken) token;
String username = token2.getUsername();
HomeworkEntity entity = homeWorkDao.dofindOne(username);
//用户不存在--还可以根据不同情况进行异常抛出
if(entity==null) {
return null;//底层会抛出一个UnKnownAccountException
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("", entity.getPassword(),"");
return info;
}
}
Controlle层
@RequestMapping("/")
@ResponseBody
public JsonResult doLogin(HomeworkEntity entity){
//1.获取Subject对象
System.out.println(entity);
Subject subject=SecurityUtils.getSubject();
//2.通过Subject提交用户信息,交给shiro框架进行认证操作
//2.1对用户进行封装
UsernamePasswordToken token=
new UsernamePasswordToken(
entity.getName(),//身份信息
entity.getPassword());//凭证信息
//2.2对用户信息进行身份认证
try {
subject.login(token);
//JsonResult是对返回值得封装-可以根据具体情况而定
return new JsonResult(200,"login ok!");
}catch (UnknownAccountException e){
return new JsonResult(201,"用户不存在");
}catch (IncorrectCredentialsException e){
return new JsonResult(202,"密码错误");
}
//分析:
//1)token会传给shiro的SecurityManager
//2)SecurityManager将token传递给认证管理器
//3)认证管理器会将token传递给realm
//return new JsonResult("login ok");
}
SecurityManager配置类修改
@Bean
public SecurityManager securityManager(UserRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
以上是对shiro的安全框架–拦截与认证的主要实现、授权暂时没有(前端很简单根据情况而定)