狂神shiro笔记
shiro的快速开始
maven配置:
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
log4j的配置:
log4j.properties
ini的配置
shiro.ini
测试一下?
Quickstart
本章结束!!!!
shiro的subject分析
1. 首先使用factory(工厂)创建shiro.ini实例
2. 获取当前的用户对象(相对独立)
Subject currentUser = SecurityUtils.getSubject();
3. 通过当前用户拿到session
Session session = currentUser.getSession();
4. 登录认证
if (!currentUser.isAuthenticated()) {
//Token: 令牌 没有获取,随机设置
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
token.setRememberMe(true);//设置记住我
try {
currentUser.login(token);//执行登录操作(点击看不到)
} catch (UnknownAccountException uae) {//用户不存在
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {//用户锁定 lock
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
}
// ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {//认证异常
//unexpected condition? error?
}
}
5. 角色和权限的认证
//test a role:
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//粗力度
//test a typed permission (not instance-level)
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//细力度
//a (very powerful) Instance Level permission:
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
SpringBoot集成shiro
面试小技巧?
<!--
Subject. 用户
SecurityManager管理所有的用户
Realm连接数据
-->
1.springboot的包整合maven
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-web-starter -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.7.1</version>
</dependency>
2.编写config的配置类
PS:@Bean必须加上
- shiroFilterFactoryBean
//shiroFilterFactoryBean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroBean.setSecurityManager(securityManager); return shiroBean; }
- DefaultWebSecurityManager2
//DefaultWebSecurityManager2
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){//方法把类名引入
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
- 创建Realm对象 需要自定义1
自定义一个UserRealm. 需要继承extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm { //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection >principalCollection) { System.out.println("执行授权=====》"); return null; } //认证 @Override protected AuthenticationInfo >doGetAuthenticationInfo(AuthenticationToken authenticationToken) >throws AuthenticationException { System.out.println("执行认证=====》"); return null; } }
//创建Realm对象 需要自定义1
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
登录拦截器
//添加shiro内置过滤器
/**
* anon 无需认证皆可访问
* authc 必须认证才可以访问
* user 必须记住我才可以访问
* perms 拥有某个资源权限才可以访问
* role 拥有某个角色权限才可以访问
*
* **/
Map<String,String> map = new LinkedHashMap<>();
map.put("/admin/add","anon");
map.put("/admin/update","authc");
//设置登录请求
shiroBean.setLoginUrl("/login");
//设置一个过滤器的链
shiroBean.setFilterChainDefinitionMap(map);
用户认证
小结
请求写在第一个
用户认证写在realm
在userrealm写
静态编写用户密码认证
@RequestMapping("/loginin")
public String loginYanzheng(
String username,
String password,
Model model
){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
try {
subject.login(token);//执行登录的方法,如果没有异常就OK了
return "index";
} catch (UnknownAccountException e) {
model.addAttribute("msg","用户名不存在");
return "login";
}catch (IncorrectCredentialsException ice) {
model.addAttribute("msg","密码不存在");
return "login";
}
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行认证=====》");
String username = "jiangwenhan";
String password = "123456";
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
if(!userToken.getUsername().equals(username)){
return null;//抛出异常
}
//密码认证,shiro做
return new SimpleAuthenticationInfo("",password,"");
}
shiro和数据库的整合
PS:我是用的是JPA,使用什么都无所谓,道理都一样
认证处做了改变
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行认证=====》");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//使用真实的数据库
admin admin = this.adminDao.findByUsername(userToken.getUsername());
if(admin==null){
return null;//抛出异常
}
//密码认证,shiro做
return new SimpleAuthenticationInfo(admin,admin.getPassword(),"");
}
权限验证
主要是ShiroFilterFactoryBean里过滤器的链
List<prem> prem = this.premDao.findAll();
for (int i = 0; i < prem.size(); i++) {
map.put(prem.get(i).getSrc(),"perms[u"+prem.get(i).getId()+"]");
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权=====》");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject current = SecurityUtils.getSubject();
admin admin = (admin) current.getPrincipal();
List<rolePrem> rolePrems = this.rolePremDao.findByRoleId(admin.getRoleId());
for (int i = 0; i < rolePrems.size(); i++) {
info.addStringPermission("u"+rolePrems.get(i).getPremId().toString());
}
return info;
}
shiro和thymeleaf的整合
千万不要忘了config里面加入
//整合shiroDialect thymeleaf-shiro
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}