nullcy 2020-04-25
<!--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.5.2</version> </dependency>
目录如下
com
config
ShiroConfig.java
UserRealm.java
controller
RouterController.java
SpringbootShrioApplication
shiro有三个核心(配置时都必须装配成Bean):
Realm(连接数据)
开始配置ShiroConfig,从底层开始配置(从下往上),Realm需要额外写一个类UserRealm,这个类便是shiro的核心
@Configuration public class ShiroConfig{ //shriofilterbean //这个方法名必须为shiroFilterFactoryBean,否则报错 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ System.out.println(""); ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //关联securityManager bean.setSecurityManager(securityManager); //给请求设置权限 //authc:需要认证才可访问 //anon:无需认证也能访问 Map<String,String> filter = new LinkedHashMap<>(); filter.put("/user/*","authc"); filter.put("/","anon"); bean.setFilterChainDefinitionMap(filter); //当没有权限,跳转到此登陆界面 bean.setLoginUrl("/login"); return bean; } //securityManager @Bean public DefaultWebSecurityManager securityManager(@Qualifier("realm") UserRealm realm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联realm securityManager.setRealm(realm); return securityManager; } //realm @Bean public UserRealm realm(){ return new UserRealm(); }
UserRealm只需继承AuthorizingRealm类即可,要实现如下两个方法,本类为shiro核心:
//自定义的realm 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; } }
流程:
controller接受请求代码(用户提交表单时用controller接收):
@RequestMapping("/login") public String login(String usr, String pwd, Model model){ //获取当前用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登陆数据,生成令牌 UsernamePasswordToken token = new UsernamePasswordToken(usr,pwd); //用令牌登陆,如果没有异常则登陆成功 try{ subject.login(token); //无异常则登陆成功 return "index"; }catch(UnknownAccountException e){ model.addAttribute("msg","用户名错误"); return "login"; }catch(IncorrectCredentialsException e){ model.addAttribute("msg","密码错误"); return "login"; } }
getAuthenticationInfo()代码:
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("认证"); //用户名,密码,应该从数据库取,此处仅测试 String usr="wagn"; String pwd="123"; //先取令牌 UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; //验证用户名 if(!usr.equals(token.getUsername())){ return null; } //验证密码,Shiro自动验证,只需要把数据库的密码传过去就好了 return new SimpleAuthenticationInfo("",pwd,""); }