Spring Boot REST 服务和 Shibboleth 之间的手动身份验证

问题描述 投票:0回答:1

我有一个用 Java Spring Boot 编写的无状态 REST 服务的后端。

1- 其中一项服务是“/登录”。它从我自己的网络表单(不是 Shibboleth 生成的表单)接收用户名和密码。在此服务调用中,我想联系 Shibboleth(使用 OAuth2 或 SAML 或其他方式)来验证该用户并获取令牌。这应该同步完成,因为服务必须向调用者返回“true”或“false”。不允许重定向:要么 true 要么 false。

2- 此令牌将包含在发送回前端的响应中,并将存储在前端中。它将在以下对其他 REST 服务(/Login 除外)的调用中重新发送回后端。这些其他调用必须通过向 Shibboleth 发送令牌来联系 Shibboleth。 Shibboleth 必须返回有关用户的信息,如果令牌不正确,则返回错误。

如何手动实现第 1 点和第 2 点,即不使用 Spring Security?只是纯Java,也许还有其他第三方库。

java spring-boot spring-security shibboleth
1个回答
0
投票

如果您不想使用 Spring Security,您应该将令牌保存在 Redis 或包含用户 ID 及其令牌的表中。之后你应该编写过滤器。推荐使用aspect或者spring-Aop.

在每个请求中,该请求首先到达您的方面,从前端获取用户 ID 和令牌,然后从 Redis 或您的数据库获取该用户 ID 的令牌,并将它们相互比较,如果正确,您的请求将继续,如果是不正确会抛出异常。

下面有一个示例 Aop 代码

package com.dpco.aop;

import com.dpco.business.exception.CustomException;
import com.dpco.logger.Logger4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;


@Aspect
@Configuration
public class LoggerAspect {

    @Autowired
    private Logger4j logger4j;

    @Pointcut("execution(* com.dpco.controller.*.*(..)) && @annotation(requestMapping)")
    public void controller(RequestMapping requestMapping){
    }


    @Around("controller(requestMapping)")
    public Object around(ProceedingJoinPoint joinPoint , RequestMapping requestMapping) throws Throwable {

            Object[] obj = joinPoint.getArgs();
            File file = new File("log.txt");
            Object object = null;
            try {
                if (file.createNewFile()) {
                    FileWriter fileWriter = new FileWriter(file);
                    fileWriter.write("\n\n-----------------------------------------this is the logger of project , you can see the methods that calls and information of them  in here------------------------------------\n\n");
                    fileWriter.close();
                }
                FileWriter fileWriter = new FileWriter(file, true);
                Date first = new Date();
                fileWriter.write("\n---------------------------------------" + joinPoint.getSignature().getName() + "-------------------------------------------\n");
                fileWriter.write("path is : " + requestMapping.path()[0] + "\n");
                fileWriter.write("the method of request is :" + requestMapping.method()[0] + "\n");
                StringBuilder builder = new StringBuilder();
                for (Object arg : obj) {
                    builder.append(arg.toString() + ",");
                }
                if(builder.length() != 0) {
                    builder.deleteCharAt(builder.indexOf(builder.toString()));
                }
                fileWriter.write("the arguments of this method is : " + builder.toString() + "\n");
                object = joinPoint.proceed();
                Date second = new Date();
                fileWriter.write("the milli seconds that left : " + String.valueOf(second.getTime() - first.getTime()));
                fileWriter.close();
            } catch (IOException e) {
                logger4j.getLogger(e);
                throw new CustomException("hello", HttpStatus.MULTI_STATUS);
            }
            return object;

    }



}

此方面包含每次调用休息控制器之前的日志

您可以根据您的需要进行更改。

我认为根据您的需求这是最好的方法

© www.soinside.com 2019 - 2024. All rights reserved.