Shiro 权限控制
Shiro 概念
Shiro系统交互流程
subject——>SecurityManage——>认证器——>realm
Shiro认证
认证原理
subject.login——>SecurityManager——>realm——>访问db,验证登录用户
过滤器
三个重要的过滤器
- anon 免认证过滤器
- authc 认证过滤器
-
认证实现
shiro 依赖包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.0</version>
</dependency>
创建 ShiroRealm
public class ShiroRealm extends AuthorizingRealm {
//授权校验方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
}
编写配置类 ShiroCofig
```java @Configuration public class ShiroConfig { // 1.创建realm,加入ioc容器 @Bean public ShiroRealm shiroRealm() {
ShiroRealm shiroRealm = new ShiroRealm();
return shiroRealm;
}
//创建securityManager对象,注入realm @Bean public SecurityManager securityManager(ShiroRealm shiroRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(shiroRealm);
return securityManager;
}
@Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
//创建过滤工厂
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//设置securityManager安全管理对象
factoryBean.setSecurityManager(securityManager);
//设置登录页面的地址,当没有认证或认证失败的时候自动跳转到该页面
factoryBean.setLoginUrl("Login.html");
//授权校验失败,默认跳转搭配该页面
factoryBean.setUnauthorizedUrl("unauthorizedUrl.html");
//存储放行的资源、认证的资源
Map<String, String> map = new HashMap<>();
//匿名访问过滤器
map.put("login", "anon");
map.put("login.html", "anon");
//authc 认证过滤器,访问/**所有的资源都需要认证,除了放行的
map.put("/**", "authc");
factoryBean.setFilterChainDefinitionMap(map);
return factoryBean;
}
}
<a name="Zj9TW"></a>
### LoginController 认证
```java
@RestController
@Slf4j
@Api(tags = "登录认证")
public class LoginController {
@PostMapping("/login")
@ApiOperation(value = "认证方法")
public R<String> login(@RequestBody Users users) {
try {
//获取subject对象
Subject subject = SecurityUtils.getSubject();
//创建token,封装用户输入的账号密码
AuthenticationToken token = new UsernamePasswordToken(users.getName(), users.getPassword());
//登录认证,自动渠道realm的认证方法
subject.login(token);
log.info("登录认证成功,身份信息:{}", subject.getPrincipal());
return R.ok("登录认证成功");
} catch (AuthenticationException e) {
e.printStackTrace();
log.error("认证失败,{}", e.getMessage());
}
return R.fail("认证失败");
}
ShiroRealm 实现认证
@Slf4j
public class ShiroRealm extends AuthorizingRealm {
@Resource
private UserService userService;
//认证方法 被subject.login()调用
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取用户输入的用户名
String name = (String) token.getPrincipal();
//根据用户名查询
Users users = userService.findByName(name);
//判断
if (name == null) {
log.error("用户名不存在,{}", name);
return null;
}
//获取数据库中正确的密码
String correctPwd = users.getPassword();
//返回
//参数1
return new SimpleAuthenticationInfo(users, correctPwd, this.getName());
}
}
退出方法
@RestController
@Slf4j
@Api(tags = "登录认证")
public class LoginController {
@GetMapping("/logout")
@ApiOperation(value = "退出方法")
public R<String> login() {
SecurityUtils.getSubject().logout();
return R.ok("退出成功");
}
}
Shiro认证加密
Md5+用户名加密