package com.dcy.springbootshiro.config;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.tomcat.util.http.parser.Authorization;
/**
* @author dcy
* @date 2019/9/10 11:44
* @description
*/
public class UserRealm extends AuthorizingRealm {
/**
* 执行授权逻辑
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
return null;
}
/**
*执行认证逻辑
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//假设数据库中的用户名和密码
String name = "admin";
String password = "123";
//编写shiro判断逻辑,判断yo用户名和密码
//1、判断用户名
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
if(!token.getUsername().equals(name)){//用户名不存在
return null;//shiro底层会抛出UnknownAccountException异常
}
//2、判断密码,第一个参数,即将userInfo放到session中 ,获得的方式是
// Subject subject = SecurityUtils.getSubject(); UserInfo = subject .getPricipal();
return new SimpleAuthenticationInfo(userInfo,password,"");
}
}
package com.dcy.springbootshiro.config;
import org.apache.commons.collections.map.LinkedMap;
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;
/**
* @author dcy
* @date 2019/9/10 11:35
* @description
*/
@Configuration
public class ShiroConfig {
/**
* 创建shiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
//增加shiro内置过滤器
/**
* shiro内置过滤器,可以实现权限相关的lan拦截器
* 常用的过滤器:
* anon:无需认证(登录)可以访问
* authc:必须认证才能fwe
* user:如果使用rememberMe的功能可以直接访问
* perms:该资源必须得到权限才可以访问
* role该资源必须得到j角色权限才可以访问
*
*/
Map<String ,String> filterMap = new LinkedHashMap<String,String>();
//设置某些页面的拦截
/* filterMap.put("/user/addUser","authc");
filterMap.put("/user/updateUser","authc");*/
//去除某些拦截,注意顺序
filterMap.put("/user/hello","anon");//取消拦截登录页面的请求
filterMap.put("/user/login","anon");//取消拦截登录请求的路径
//拦截所有页面
filterMap.put("/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//修改调整的登录页面
shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
return shiroFilterFactoryBean;
}
/**
* 创建DeafultWebSecuriyManage
*/
@Bean("securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 创建realm
*/
@Bean("userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
4.4实现用户认证(登录)的操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" action="/user/login">
用户名:<input type="text" name="name"/>
密码:<input type="password" name="passwor"/>
<button type="submit" value="登录"/>
</form>
</body>
</html>
4.4.2编写 Controller的登录处理逻辑
package com.dcy.springbootshiro.controller;
import org.apache.catalina.security.SecurityUtil;
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.RestController;
/**
* @author dcy
* @date 2019/9/10 11:28
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/hello")
public String hello(){
return "test.html";
}
@RequestMapping("/addUser")
public String add(){
return "addUser.html";
}
@RequestMapping("/updateUser")
public String update(){
return "updateUser.html";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "login.html";
}
public String login(String name, String password, Model mm){
/**
* 使用shiro编写认证操作
*/
//1、获得subject
Subject subject = SecurityUtils.getSubject();
//2、封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(name,password);
//3、执行登录方法
try{
subject.login(token);
//登录成功
return "redirect:/user/hello";
} catch (UnknownAccountException e){
//登录失败
mm.addAttribute("msg","用户名不存在");
return "login";
} catch (IncorrectCredentialsException e){
//登录事变
mm.addAttribute("msg","密码错");
return "login";
}
}
}
执行登录处理的时候, subject.login(token);会到自定义的realm中的执行认证逻辑的方法进行处理。