【问题标题】:Java Spring RestController cannot implement custom interfaceJava Spring RestController 无法实现自定义接口
【发布时间】:2021-01-10 01:58:02
【问题描述】:

我是 Spring 的新手,我的任务是创建一个应用程序,通过使用 Azure Active Directory 对用户进行身份验证来启用 SSO。我有一个严格的规则,我需要使用定义一种方法的接口(由供应商提供):

public String authenticate(HttpServletRequest request);

将从我们供应商的软件中调用此方法以验证用户身份。返回的字符串必须是用户主体名称。我遵循了有关如何使用 Spring Security 合并 Azure Active Directory 的官方文档,并且能够在控制器中检索我的用户信息!我遇到的问题是当我实现供应商接口时该方法不再起作用并报告以下错误消息:

出现意外错误(类型=未找到,状态=404)。

我在网上进行了研究,您可以在接口级别进行注释并在控制器上实现它,但我无法访问供应商接口,该接口仅通过外部 JAR 文件提供给我。我还看到了可以更新 application.properties 文件并将以下参数设置为 true 的建议,但这没有帮助:

spring.aop.proxy-target-class=true

任何帮助都会很棒,如果我因为对生态系统不熟悉而错过了任何重要细节,我深表歉意。以下是我的代码:

AuthController:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.access.prepost.PreAuthorize;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.generic.CustomerVendorInterface;


@RestController
public class AuthController implements CustomVendorInterface {

   @RequestMapping("/")
   @PreAuthorize("isAuthenticated()")
   @Override
   public String authenticate(HttpServletRequest request) {
       String username = null;
       OAuth2User user = ((OAuth2AuthenticationToken)request.getUserPrincipal()).getPrincipal();
       if (user != null)
           username = user.getAttribute("upn");
       return username;
   }
}

WebSecurityConfig:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
    }
}

【问题讨论】:

  • 你是如何将 AuthController 传递给库的?

标签: java spring-boot spring-restcontroller spring-annotations


【解决方案1】:

我建议将您的控制器和身份验证分成不同的类。以下是实现CustomVenderInterface的方法:

@Component
public class Authenticator implements CustomVenderInterface {

   @Override
   public String authenticate(HttpServletRequest request) {
       String username = null;
       OAuth2User user = ((OAuth2AuthenticationToken)request.getUserPrincipal()).getPrincipal();
       if (user != null)
           username = user.getAttribute("upn");
       return username;
   }

}

那么您的控制器类将如下所示:

@RestController
public class AuthController {
  
   private final Authenticator authenticator;

   public AuthController(Authenticator authenticator) {
       this.authenticator = authenticator;
   }

   @RequestMapping("/")
   @PreAuthorize("isAuthenticated()")
   public String handleAuthRequest(HttpServletRequest request) {
       return authenticator.authenticate(request);
   }
}

请说明您如何将 CustomVenderInterface 传递给供应商的库。

【讨论】:

  • 没有机会发表评论,但您提出的解决方案最终奏效了!感谢您的帮助
猜你喜欢
  • 2017-08-07
  • 2015-12-01
  • 1970-01-01
  • 2020-05-02
  • 1970-01-01
  • 2020-10-02
  • 2018-07-17
  • 1970-01-01
  • 2021-09-30
相关资源
最近更新 更多