今天学习了shiro,这是一个和spring Security很像的一个安全框架。但是shiro的可定制化更高。
三个核心组件:Subject, SecurityManager 和 Realms.
Subject:
即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager:
它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:
Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
ShiroFilterFactoryBean过滤器配置
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
//添加shiro的过滤器
/**
* anon:无需认证就可以访问
* anthc:必须认证以后才能访问
* user:必须使用记住我功能后才能使用
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色权限才能访问
*/
//拦截
Map<String,String> filterMap=new LinkedHashMap<>();
//授权,正常情况下,没有授权会跳转到未授权页面
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
filterMap.put("/user/*","authc");//可以使用通配符
// filterMap.put("/user/add","authc");
// filterMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterMap);
bean.setSecurityManager(defaultWebSecurityManager);
//设置登录的请求
bean.setLoginUrl("/toLogin");
//未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//defaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//Realm:这是自己写的一个Realm类,将他注入到spring中
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
自己写的realm类
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=》授权");
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermission("user:add");
//拿到当前对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到user对象
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=》认证");
// String name="admin";
// String password="123456";
//这里是从token里面拿到的封装好的登录用户的信息,步骤在controller里面
UsernamePasswordToken userToken= (UsernamePasswordToken) token;
User user = userService.queryUser(userToken.getUsername());
if (user==null){
return null;
}
//密码认证,shiro自己做
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
controller:
@RequestMapping("/login")
private String login(String username, String password, Model model){
if (username==null||password==null){
System.out.println("传值错误");
}else {
System.out.println(username+password);
}
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);//执行登录方法
return "index";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "login";
} catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
这就是shiro的简单使用了,如果有写的不对的地方,欢迎各位大神指正