shiro
shiro的两个主要目的是“认证”和“授权(访问控制)”
“认证”:authentication,你是什么!!
”授权“:authorization,你能干什么!!
这个概念是通用的。
shiro
ShiroConfig:
package com.fish.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig{
//creat shiroFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultSecurityManager defaultSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
/*
1.anon: 无需认证就可以访问
2.authc: 必须认证了才能访问
3.user: 必须拥有 ~记住我~ 功能才能访问
4.perms: 拥有对于某个资源的权限才能访问
5.role: 拥有某个角色权限才能访问
* */
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","authc");
filterMap.put("/user/update","perms[user:update]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
shiroFilterFactoryBean.setLoginUrl("/login");
return shiroFilterFactoryBean;
}
//creat SecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
//creat userRealm
@Bean(name = "userRealm")
public UserRealm getUserRealm(){
return new UserRealm();
}
@Bean
public ShiroDialect ShiroDialect(){
return new ShiroDialect();
}
}
UserRealm:
package com.fish.config;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("=======进入到授权=======");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addStringPermission("user:update");
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("=======进入到认证=======");
String userName="root";
String password="123456";
UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
System.out.println(token.getUsername() + "=======" + token.getPassword());
if(!userName.equals(token.getUsername())){
return null; //返回空值就意味着用户名错误
}
//进行密码检测,shiro帮助我们进行密码检测
return new SimpleAuthenticationInfo("",password,"");
}
}
RouterConteroller
package com.fish.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class RouterController {
@RequestMapping({"/index","/"})
public String toIndex(){
return "index";
}
@RequestMapping("/user/add")
public String toAdd(){
return "user/add";
}
@RequestMapping("/user/update")
public String toUpdate(){
return "user/update";
}
@RequestMapping("/login")
public String toLogin(){
return "login";
}
@RequestMapping("/toLogin")
public String login(@RequestParam("username") String userName, @RequestParam("password") String password, Model model){
//获取当前用户对象
Subject subject = SecurityUtils.getSubject();
//获取传入的用户名和密码,将其封装至token令牌中
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userName, password);
try {
//subject登录带着令牌进入到userRealm中进行认证
subject.login(usernamePasswordToken);
return "index";
}catch (UnknownAccountException e){
//用户名错误
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
//Credentials: 资格
//密码错误
model.addAttribute("msg","密码错误");
return "login";
}
}
@RequestMapping("/unauthorized")
@ResponseBody
public String unauthorized(){
return "未经授权";
}
}
和thymeleaf整合过程中的注意事项:
- ShiroConfig配置类中shiroDialect组件中漏写(这个组件代表着和thymeleaf整合)
- html页面中的命名空间为:xmlns:shiro=“http://www.pollix.at/thymeleaf/shiro”
吐槽:使用shiro时,在HTML页面上匹配权限时,使用冒号,页面会提示错误(未解决)。
至此,感谢B站狂神说的教学视频!!