SpringBoot集成Shiro(二)验证用户角色
SpringBoot集成Shiro(三)验证用户权限
SpringBoot集成Shiro(四)验证用户角色升级版
学习这篇文章之前,需要对 shiro 有一个简单的了解。
在SpringBoot中集成Shiro安全认证框架也很简单,大概可以分为以下几步:
首先在 https://start.spring.io/ 创建一个SpringBoot项目,在创建的时候把 Spring Web 依赖加上:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
我们创建一个 UserController 来实现登录业务
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("login")
public String Login(String username, String password){
System.out.println("开始登录 username:" + username +", password:" + password);
return "Login successful";
}
}
完成这一步之后,其实我们的项目已经可以跑起来了,我们运行项目,然后在浏览器输入:localhost:8080/user/login 就能访问到我们这个方法了。我们试一下:
在控制台应该能够看到我们的打印:
开始登录 username:null, password:null
在浏览器应该能看到返回值的字符串:
Login successful
接下来我们将改造这个 login 方法,用 shiro 的方式来实现登录:
@RequestMapping("login")
public String Login(String username, String password){
System.out.println("开始登录 username:" + username +", password:" + password);
// 获取 Subject
Subject subject = SecurityUtils.getSubject();
// 根据用户名和密码创建 Token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
// 通过 subject 去登录
subject.login(token);
}catch (UnknownAccountException e){
System.out.println("账号不存在");
return "Login failed";
}catch (IncorrectCredentialsException e){
System.out.println("密码不正确");
return "Login failed";
}catch (Exception e){
e.printStackTrace();
}
return "Login successful";
}
改造之后发生了一些变化,首先,我们使用 SecurityUtils 工具类创建一个 Subject,然后使用用户名密码创建了一个 UsernamePasswordToken。最后我们将 Token 传入 Subject的 login 方法中去进行登录。在最后的最后,我还捕获了几个异常,身份验证失败的时候一定记得捕获 AuthenticationException 或其子类,常见的如:
接下来我们再来实现用户名和密码的验证功能
我们需要创建一个类,然后继承 AuthorizingRealm,并实现它的两个方法:一个是授权方法,一个是认证方法
public class UserRealm extends AuthorizingRealm {
// 这是验证用户权限使用的方法,暂时先不管。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证方法
*
* 执行 subject.login() 方法时 就会调用本方法进行认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("进入身份认证器......");
// 用户名密码(这两个数据应该从数据库查询出来)
String DB_Username="admin";
String DB_Password="123456";
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
DB_Username, //用户名
DB_Password, //密码
ByteSource.Util.bytes(DB_Password.getBytes()),
getName() //realm name
);
return authenticationInfo;
}
}
在 doGetAuthenticationInfo 认证方法中,我将用户名和密码写死了,真实项目中,这个数据应该是从数据库查询出来的。通过 token.getPrincipal();就可以获取到 token 中的用户名了,然后根据用户名去数据库查询User数据就好了。
用户验证的逻辑已经完成了,接下来进入最后的步骤,配置!!
我们使用 JavaConfig 的方式来配置:
@Configuration
public class ShiroConfig {
/**
* 第三步
* 注册 ShiroFilterFactoryBean
* @return ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
// 创建 ShiroFilterFactoryBean
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 将SecurityManager实例 并绑定给 ShiroFilterFactoryBean
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
/**
* 第一步
* 注册UserRealm
* @return UserRealm
*/
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
/**
* 第二步
* 注册SecurityManager
* @return SecurityManager
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
return securityManager;
}
}
根据引用顺序,我将上面三个 bean 分为了三步。
可以看到登录验证成功了。
完整代码可到此处下载:springboot-shiro-demo
这是 SpringBoot 集成 Shiro 最简单的配置,后续其他的安全操作都可以在这个基础上扩展。下篇文章我们学习:如何控制用户角色。
技 术 无 他, 唯 有 熟 尔。
知 其 然, 也 知 其 所 以 然。
踏 实 一 些, 不 要 着 急, 你 想 要 的 岁 月 都 会 给 你。