Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

网友投稿 269 2022-10-28


Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

Shiro简介

Apache Shiro是一个强大且易用的java安全框架,执行身份验证、授权、密码和会话管理

三个核心组件:Subject, SecurityManager 和 Realms

Subject代表了当前用户的安全操作

SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

Shiro快速入门

导入依赖

org.apache.shiro

shiro-core

1.7.1

org.slf4j

jcl-over-slf4j

2.0.0-alpha1

org.slf4j

slf4j-log4j12

2.0.0-alpha1

log4j

log4j

1.2.17

配置log4j.properties

log4j.rootLogger=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

# General Apache libraries

log4j.logger.org.apache=WARN

# Spring

log4j.logger.org.springframework=WARN

# Default Shiro logging

log4j.logger.org.apache.shiro=INFO

# Disable verbose logging

log4j.logger.org.apache.shiro.util.ThreadContext=WARN

log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

配置Shiro.ini(在IDEA中需要导入ini插件)

[users]

# user 'root' with password 'secret' and the 'admin' role

root = secret, admin

# user 'guest' with the password 'guest' and the 'guest' role

guest = guest, guest

# user 'presidentskroob' with password '12345' ("That's the same combination on

# my luggage!!!" ;)), and role 'president'

presidentskroob = 12345, president

# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'

darkhelmet = ludicrousspeed, darklord, schwartz

# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'

lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------

# Roles with assigned permissions

#

# Each line conforms to the format defined in the

# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc

# -----------------------------------------------------------------------------

[roles]

# 'admin' role has all permissions, indicated by the wildcard '*'

admin = *

# The 'schwartz' role can do anything (*) with any lightsaber:

schwartz = lightsaber:*

# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with

# license plate 'eagle5' (instance specific id)

goodguy = winnebago:drive:eagle5

快速入门实现类 quickStart.java

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.*;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.DefaultSecurityManager;

import org.apache.shiro.realm.text.IniRealm;

import org.apache.shiro.session.Session;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class quickStart {

private static final transient Logger log = LoggerFactory.getLogger(quickStart.class);

/*

Shiro三大对象:

Subject: 用户

SecurityManager:管理所有用户

Realm: 连接数据

*/

public static void main(String[] args) {

// 创建带有配置的Shiro SecurityManager的最简单方法

// realms, users, roles and permissions 是使用简单的INI配置。

// 我们将使用可以提取.ini文件的工厂来完成此操作,

// 返回一个SecurityManager实例:

// 在类路径的根目录下使用shiro.ini文件

// (file:和url:前缀分别从文件和url加载):

//Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");

//SecurityManager securityManager = factory.getInstance();

DefaultSecurityManager securityManager = new DefaultSecurityManager();

IniRealm iniRealm = new IniRealm("classpath:shiro.ini");

securityManager.setRealm(iniRealm);

// 对于这个简单的示例快速入门,请使SecurityManager

// 可作为JVM单例访问。大多数应用程序都不会这样做

// 而是依靠其容器配置或web.xml进行

// webapps。这超出了此简单快速入门的范围,因此

// 我们只做最低限度的工作,这样您就可以继续感受事物.

SecurityUtils.setSecurityManager(securityManager);

// 现在已经建立了一个简单的Shiro环境,让我们看看您可以做什么:

// 获取当前用户对象 Subject

Subject currentUser = SecurityUtils.getSubject();

// 使用Session做一些事情(不需要Web或EJB容器!!!

Session session = currentUser.getSession();//通过当前用户拿到Session

session.setAttribute("someKey", "aValue");

String value = (String) session.getAttribute("someKey");

if (value.equals("aValue")) {

log.info("Retrieved the correct value! [" + value + "]");

}

// 判断当前用户是否被认证

if (!currentUser.isAuthenticated()) {

//token : 令牌,没有获取,随机

UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");

token.setRememberMe(true); // 设置记住我

try {

currentUser.login(token);//执行登陆操作

} catch (UnknownAccountException uae) {//打印出 用户名

log.info("There is no user with username of " + token.getPrincipal());

} catch (IncorrectCredentialsException ice) {//打印出 密码

log.info("Password for account " + token.getPrincipal() + " was incorrect!");

} catch (LockedAccountException lae) {

log.info("The account for username " + token.getPrincipal() + " is locked. " +

"Please contact your administrator to unlock it.");

}

// ... 在此处捕获更多异常(也许是针对您的应用程序的自定义异常?

catch (AuthenticationException ae) {

//unexpected condition? error?

}

}

//say who they are:

//print their identifying principal (in this case, a username):

log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

//test a role:

if (currentUser.hasRole("schwartz")) {

log.info("May the Schwartz be with you!");

} else {

log.info("Hello, mere mortal.");

}

//test a typed permission (not instance-level)

if (currentUser.isPermitted("lightsaber:wield")) {

log.info("You may use a lightsaber ring. Use it wisely.");

} else {

log.info("Sorry, lightsaber rings are for schwartz masters only.");

}

//a (very powerful) Instance Level permission:

if (currentUser.isPermitted("winnebago:drive:eagle5")) {

log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +

"Here are the keys - have fun!");

} else {

log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");

}

//all done - log out!

currentUser.logout();//注销

System.exit(0);//退出

}

}

启动测试

SpringBoot-Shiro整合(最后会附上完整代码)

前期工作

导入shiro-spring整合包依赖

org.apache.shiro

shiro-spring

1.7.1

跳转的页面

index.html

add| update

add.html

add

update.html

http://

update

编写shiro的配置类ShiroConfig.java

package com.example.config;

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 {

//3. ShiroFilterFactoryBean

@Bean

public ShiroFilterFactoryBean getshiroFilterFactoryBean(@Qualifier("SecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){

ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

factoryBean.setSecurityManager(defaultWebSecurityManager);

return factoryBean;

}

//2.创建DefaultWebSecurityManager

@Bean(name = "SecurityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){

DefaultWebSecurityManager SecurityManager=new DefaultWebSecurityManager();

//3.关联Realm

SecurityManager.setRealm(userRealm);

return SecurityManager;

}

//1.创建Realm对象

@Bean(name = "userRealm")

public UserRealm userRealm(){

return new UserRealm();

}

}

编写UserRealm.java

package com.example.config;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authz.AuthorizationInfo;

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("授权");

return null;

}

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("认证");

return null;

}

}

编写controller测试环境是否搭建好

package com.example.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class MyController {

@RequestMapping({"/","/index"})

public String index(Model model){

model.addAttribute("msg","hello,shiro");

return "index";

}

@RequestMapping("/user/add")

public String add(){

return "user/add";

}

@RequestMapping("/user/update")

public String update(){

return "user/update";

}

}

实现登录拦截

在ShiroConfig.java文件中添加拦截

Map filterMap = new LinkedHashMap<>();

//对/user/*下的文件只有拥有authc权限的才能访问

filterMap.put("/user/*","authc");

//将Map存放到ShiroFilterFactoryBean中

factoryBean.setFilterChainDefinitionMap(filterMap);

这样,代码跑起来,你点击add或者update就会出现404错误,这时候,我们再继续添加,让它跳转到我们自定义的登录页

添加登录拦截到登录页

//需进行权限认证时跳转到toLogin

factoryBean.setLoginUrl("/toLogin");

//权限认证失败时跳转到unauthorized

factoryBean.setUnauthorizedUrl("/unauthorized");

login.html

用户名:

密码:

视图跳转添加一个login页面跳转

@RequestMapping("/toLogin")

public String login(){

return "login";

}

上面,我们已经成功拦截了,现在我们来实现用户认证

首先,我们需要一个登录页面

login.html

用户名:

密码:

其次,去controller编写跳转到登录页面

@RequestMapping("/login")

public String login(String username,String password,Model model){

//获得当前的用户

Subject subject = SecurityUtils.getSubject();

//封装用户数据

UsernamePasswordToken taken = new UsernamePasswordToken(username,password);

try{//执行登陆操作,没有发生异常就说明登陆成功

subject.login(taken);

return "index";

}catch (UnknownAccountException e){

model.addAttribute("msg","用户名错误");

return "login";

}catch (IncorrectCredentialsException e){

model.addAttribute("msg","密码错误");

return "login";

}

}

最后去UserRealm.java配置认证

//认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("认证");

String name = "root";

String password = "123456";

UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

if (!userToken.getUsername().equals(name)){

return null;//抛出异常 用户名错误那个异常

}

//密码认证,shiro自己做

return new SimpleAuthenticationInfo("",password,"");

}

运行测试,成功!!!

附上最后的完整代码

pom.xml引入的依赖

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.4.4

com.example

springboot-08-shiro

0.0.1-SNAPSHOT

springboot-08-shiro

Demo project for Spring Boot

1.8

org.apache.shiro

shiro-spring

1.7.1

org.springframework.boot

spring-boot-starter-thymeleaf

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.4.4

com.example

springboot-08-shiro

0.0.1-SNAPSHOT

springboot-08-shiro

Demo project for Spring Boot

1.8

org.apache.shiro

shiro-spring

1.7.1

org.springframework.boot

spring-boot-starter-thymeleaf

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-maven-plugin

静态资源

index.html

add| update

login.html

用户名:

密码:

add.html

add

update.html

update

controller层

MyController.java

package com.example.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;

@Controller

public class MyController {

@RequestMapping({"/","/index"})

public String index(Model model){

model.addAttribute("msg","hello,shiro");

return "index";

}

@RequestMapping("/user/add")

public String add(){

return "user/add";

}

@RequestMapping("/user/update")

public String update(){

return "user/update";

}

@RequestMapping("/toLogin")

public String toLogin(){

return "login";

}

@RequestMapping("/login")

public String login(String username,String password,Model model){

//获得当前的用户

Subject subject = SecurityUtils.getSubject();

//封装用户数据

UsernamePasswordToken taken = new UsernamePasswordToken(username,password);

try{//执行登陆操作,没有发生异常就说明登陆成功

subject.login(taken);

return "index";

}catch (UnknownAccountException e){

model.addAttribute("msg","用户名错误");

return "login";

}catch (IncorrectCredentialsException e){

model.addAttribute("msg","密码错误");

http:// return "login";

}

}

}

config文件

ShiroConfig.java

package com.example.config;

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 {

//4. ShiroFilterFactoryBean

@Bean

public ShiroFilterFactoryBean getshiroFilterFactoryBean(@Qualifier("SecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){

ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

//5. 设置安全管理器

factoryBean.setSecurityManager(defaultWebSecurityManager);

/* shiro内置过滤器

anon 无需授权、登录就可以访问,所有人可访。

authc 需要登录授权才能访问。

authcBasic Basic HTTP身份验证拦截器

logout 退出拦截器。退出成功后,会 redirect到设置的/URI

noSessionCreation 不创建会话连接器

perms 授权拦截器,拥有对某个资源的权限才可访问

port 端口拦截器

rest rest风格拦截器

roles 角色拦截器,拥有某个角色的权限才可访问

ssl ssl拦截器。通过https协议才能通过

user 用户拦截器,需要有remember me功能方可使用

*/

Map filterMap = new LinkedHashMap<>();

//对/user/*下的文件只有拥有authc权限的才能访问

filterMap.put("/user/*","authc");

//将Map存放到ShiroFilterFactoryBean中

factoryBean.setFilterChainDefinitionMap(filterMap);

//需进行权限认证时跳转到toLogin

factoryBean.setLoginUrl("/toLogin");

//权限认证失败时跳转到unauthorized

factoryBean.setUnauthorizedUrl("/unauthorized");

return factoryBean;

}

//2.创建DefaultWebSecurityManager

@Bean(name = "SecurityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){

DefaultWebSecurityManager SecurityManager=new DefaultWebSecurityManager();

//3.关联Realm

SecurityManager.setRealm(userRealm);

return SecurityManager;

}

//1.创建Realm对象

@Bean(name = "userRealm")

public UserRealm userRealm(){

return new UserRealm();

}

}

UserRealm.java

package com.example.config;

import org.apache.shiro.authc.*;

import org.apache.shiro.authz.AuthorizationInfo;

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("授权");

return null;

}

//认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("认证");

String name = "root";

String password = "123456";

UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

if (!userToken.getUsername().equals(name)){

return null;//抛出异常 用户名错误那个异常

}

//密码认证,shiro自己做

return new SimpleAuthenticationInfo("",password,"");

}

}

但是,我们在用户认证这里,真实情况是从数据库中取的,所以,我们接下来去实现一下从数据库中取出数据来实现用户认证

Shiro整合mybatis

前期工作

在前面导入的依赖中,继续添加以下依赖

mysql

mysql-connector-java

log4j

log4j

1.2.17

com.alibaba

druid

1.2.5

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.4

org.projectlombok

lombok

导入了mybatis和Druid,就去application.properties配置一下和Druid

Druid

spring:

datasource:

username: root

password: 123456

url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8

driver-class-name: com.mysql.cj.jdbc.Driver

type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源

#Spring Boot 默认是不注入这些属性值的,需要自己绑定

#druid 数据源专有配置

initialSize: 5

minIdle: 5

maxActive: 20

maxWait: 60000

timeBetweenEvictionRunsMillis: 60000

minEvictableIdleTimeMillis: 300000

validationQuery: SELECT 1 FROM DUAL

testWhileIdle: true

testOnBorrow: false

testOnReturn: false

poolPreparedStatements: true

#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入

#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority

#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j

filters: stat,wall,log4j

maxPoolPreparedStatementPerConnectionSize: 20

useGlobalDataSourceStat: true

connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

mybatis

mybatis:

type-aliases-package: com.example.pojo

mapper-locations: classpath:mapper/*.xml

连接数据库

编写实http://体类

package com.example.pojo;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

@Data

@AllArgsConstructor

@NoArgsConstructor

public class User {

private Integer id;

private String name;

private String pwd;

}

编写mapper

package com.example.mapper;

import com.example.pojo.User;

import org.apache.ibatis.annotations.Mapper;

import org.springframework.stereotype.Repository;

@Repository

@Mapper

public interface UserMapper {

public User getUserByName(String name);

}

编写mapper.xml

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select * from mybatis.user where name=#{name}

编写service

package com.example.service;

import com.example.pojo.User;

public interface UserService {

public User getUserByName(String name);

}

package com.example.service;

import com.example.mapper.UserMapper;

import com.example.pojo.User;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

@Service

public class UserServiceImpl implements UserService{

@Autowired

UserMapper userMapper;

@Override

public User getUserByName(String name) {

return userMapper.getUserByName(name);

}

}

使用数据库中的数据

修改UserRealm.java即可

package com.example.config;

import com.example.pojo.User;

import com.example.service.UserService;

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.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {

@Autowired

UserService userService;

//授权

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

System.out.println("授权");

return null;

}

//认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("认证");

UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

//连接真实的数据库

User user = userService.getUserByName(userToken.getUsername());

if (user==null){

return null;//抛出异常 用户名错误那个异常

}

//密码认证,shiro自己做

return new SimpleAuthenticationInfo("",user.getPwd(),"");

}

}

认证搞完了,我们再来看看授权

在ShiroConfig.java文件加入授权,加入这行代码: filterMap.put("/user/add","perms[user:add]");//只有拥有user:add权限的人才能访问add,注意授权的位置在认证前面,不然授权会认证不了;

运行测试:add页面无法访问

授权同理:filterMap.put("/user/update","perms[user:update]");//只有拥有user:update权限的人才能访问update

自定义一个未授权跳转页面

在ShiroConfig.java文件设置未授权时跳转到unauthorized页面,加入这行代码:

factoryBean.setUnauthorizedUrl("/unauthorized"); 2. 去Mycontroller写跳转未授权页面

@RequestMapping("/unauthorized")

@ResponseBody//懒得写界面,返回一个字符串

public String unauthorized(){

return "没有授权,无法访问";

}

运行效果:

从数据库中接受用户的权限,进行判断

在数据库中添加一个属性perms,相应的实体类也要修改

修改UserRealm.java

package com.example.config;

import com.example.pojo.User;

import com.example.service.UserService;

import org.apache.shiro.SecurityUtils;

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;

import org.apache.shiro.subject.Subject;

import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {

@Autowired

UserService userService;

//授权

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

System.out.println("授权");

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//没有使用数据库,直接自己设置的用户权限,给每个人都设置了,现实中要从数据库中取

//info.addStringPermission("user:add");

//从数据库中得到权限信息

//获得当前登录的对象

Subject subject = SecurityUtils.getSubject();

//拿到User对象,通过getPrincipal()获得

User currentUser = (User) subject.getPrincipal();

//设置当前用户的权限

info.addStringPermission(currentUser.getPerms());

return info;

}

//认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("认证");

UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

//连接真实的数据库

User user = userService.getUserByName(userToken.getUsername());

if (user==null){

return null;//抛出异常 用户名错误那个异常

}

//密码认证,shiro自己做

return new SimpleAuthenticationInfo(user,user.getPwd(),"");

}

}

有了授权后,就又出现了一个问题,我们是不是要让用户没有权限的东西,就看不见呢?这时候,就出现了Shiro-thymeleaf整合

Shiro-thymeleaf整合

导入整合的依赖

com.github.theborakompanioni

thymeleaf-extras-shiro

2.0.0

在ShiroConfig整合ShiroDialect

//整合ShiroDialect: 用来整合 shiro thymeleaf

@Bean

public ShiroDialect getShiroDialect(){

return new ShiroDialect();

}

修改index页面

xmlns:shiro="http://thymeleaf.org/thymeleaf-extras-shiro">

登录

add

update

判断是否有用户登录

//这个是整合shiro和thymeleaf用到的,让登录按钮消失的判断

Subject subject = SecurityUtils.getSubject();

Session session = subject.getSession();

session.setAttribute("loginUser", user);

测试

以上就是Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)的详细内容,更多关于Java安全框架——Shiro的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:递归函数
下一篇:C语言分析数据包程序
相关文章

 发表评论

暂时没有评论,来抢沙发吧~