(SSM+SE)SSO(2 resource)

博客介绍了resource部分的配置过程。先新建common模块存放公用代码,在auth中添加依赖并测试。接着配置resource,修改JwtUtil工具类,配置拦截器及作用范围,配置SE配置文件。还通过SSM写接口,用注解设置访问权限,最后用postman测试,管理员无删除权限测试通过。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们开始resource部分的配置:
先做一下准备工作:
我们新建一个common的module,用于存放公用的代码,比如上次使用的两个工具类以及实体对象类:
在这里插入图片描述

pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>HandSomeAq_SSO</artifactId>
        <groupId>com.hd</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>
</project>

将需要的文件拷贝过来:
在这里插入图片描述
最后在auth中添加common的依赖:

        <dependency>
            <groupId>com.hd</groupId>
            <artifactId>common</artifactId>
            <version>1.0.0</version>
        </dependency>

运行auth查看是否正常。

完成后进行下面的步骤:配置resource部分

我们需要让登录后获得token的用户才可以访问资源,所以我们需要一个拦截器来判断请求是否携带token。
首先修改JwtUtil工具类,增加两个方法,用于解析token及判断token是否有效。

//    解析token
    public static Claims getClaimsFromToken(String token){
        return Jwts.parser()
                .setSigningKey(salt)
                .parseClaimsJws(token)
                .getBody();
    }
//判断token是否有效
    public static boolean isTokenExpired(String token){
        Claims claims = getClaimsFromToken(token);
        Date expiration = claims.getExpiration();
        return expiration.before(new Date());
    }

接着我们配置拦截器,首先在pom里添加web依赖和common依赖:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hd</groupId>
            <artifactId>common</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

创建TokenInterceptor并继承HandlerInterceptor,
稍微解释一下,HandlerInterceptor用三个抽象类
在这里插入图片描述
preHandler:在Controller执行之前调用
postHandler:controller执行之后,且页面渲染之前调用
afterCompletion:页面渲染之后调用,一般用于资源清理操作

所以我们要使用的就是preHandler方法。

package Interceptor;

import com.hd.utils.JwtUtil;
import com.hd.utils.WebUtils;
import io.jsonwebtoken.Claims;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class TokenInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception
    {
        String token = request.getHeader("token");
        if ("".equals(token) || token == null){
            throw new RuntimeException("please login");
        }
        if (JwtUtil.isTokenExpired(token)){
            throw new RuntimeException("time run out,please login again");
        }
        Claims claims = JwtUtil.getClaimsFromToken(token);
        List<String> list = (List<String>) claims.get("authorities");
        String[] strings = list.toArray(new String[list.size()]);
        UserDetails userDetails = User.builder()
                .username((String) claims.get("username"))
                .password("")
                .authorities(strings)
                .build();

        //        构建Security权限交互对象
        PreAuthenticatedAuthenticationToken authenticationToken =
                new PreAuthenticatedAuthenticationToken(
                        userDetails,
                        userDetails.getPassword(),
                        userDetails.getAuthorities()
                );
        authenticationToken.setDetails(new WebAuthenticationDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        return true;

    }
}

接下来创建拦截器配置文件配置拦截器的作用范围:

package Config;

import Interceptor.TokenInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

public class WebConfig implements WebMvcConfigurer {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor())
        //对所有的目录进行拦截
                .addPathPatterns("/**");

配置一下SE的配置文件:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                .disable();
        http
                .authorizeRequests()
                .anyRequest()
                //因为由拦截器来做验证,所以把访问全部打开
                .permitAll();
    }
}

自己通过SSM的方式写几个接口进行测试:

@RestController
@RequestMapping("/logs")
public class LogsController {
    @Autowired
    private LogsService logsService;
    @GetMapping("/getLogs")
    //访问控制:角色限定
    @PreAuthorize("hasRole('超级管理员')")
    public List<Logs> findLogsByUsername(String Username){
        return logsService.findLogsByUsername(Username);
    }
    @GetMapping("/delete")
    //访问控制:权限限定 (CRUD)
    @PreAuthorize("hasAuthority('sys:res:delete')")
    public String doDelete(){
        return "delete success!";
    }
}

@PreAuthorize(“hasRole(‘超级管理员’)”)意味着只有超级管理员可以访问;
@PreAuthorize(“hasAuthority(‘sys:res:delete’)”)意味着只有拥有删除权限的角色可以访问.

最后通过postman进行测试:

在这里插入图片描述
在这里插入图片描述
登录的角色是管理员但没有删除的权限,测试通过.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值