Spring Security Oauth2仅显示非api请求的登录页面

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

我正在使用spring boot 1.5.6和OAuth2和JWT的安全性

~/repos/jtor > mvn dependency:tree | grep security
[INFO] +- org.springframework.security.oauth:spring-security-oauth2:jar:2.0.14.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-core:jar:4.2.3.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-config:jar:4.2.3.RELEASE:compile
[INFO] |  +- org.springframework.security:spring-security-web:jar:4.2.3.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-jwt:jar:1.0.8.RELEASE:compile
[INFO] \- org.springframework.security:spring-security-test:jar:4.2.3.RELEASE:test

通过以下配置,对//api/person的请求将生成标准OAuth 401:

{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}

我想要的是要求/api/**获取401,而任何其他请求(如//welcome)被重定向(302)到我的授权服务器(Ping Federate)。登录后,我将被重定向回来,我的GET到/将返回我的HTML(或其他)。

换句话说,对API的调用需要一个令牌,而非api调用将遵循oauth2代码流。

我的配置:

security:
  basic:
    enabled: false
  oauth2:
    client:
      accessTokenUri: https://ping-dev.my-comp.com:9031/as/token.oauth2
      userAuthorizationUri: https://ping-dev.my-comp.com:9031/as/authorization.oauth2
      logoutUri: https://ping-dev.my-comp.com:9031/ext/logout
      clientId: oauth2
      clientSecret: foo
      authentication-scheme: header
    resource:
      jwt:
        keyValue: |
          -----BEGIN PUBLIC KEY-----
          MY KEY HERE
          -----END PUBLIC KEY-----

我的应用程序

@SpringBootApplication
@Slf4j
public class JtorApplication {

    public static void main(String[] args) {
        SpringApplication.run(JtorApplication.class, args);
    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
           http
                   .authorizeRequests()
                   .antMatchers("/info", "/health", "/public/**").permitAll()
                   .anyRequest().fullyAuthenticated();
           // @formatter:on
        }
    }

    /*
     this class allows me to access public resources with a URL that starts with "public/", which
     allows me to bypass security on any public resource in a clean way.
     */
    @Configuration
    protected static class WebMvcConfigurer extends WebMvcConfigurerAdapter {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/");
        }
    }

    /*
    This is the API I want protected via Oauth2/JWT.
    Only calls containing a valid Bearer token should be allowed.
    Calls without a token should get back a standard Oauth 401 error
     */
    @RestController
    @RequestMapping("/api")
    protected static class ApiController {

        @GetMapping("/person")
        public Person getPerson() {
            return Person.builder().id(1).name("Jason").build();
        }

        @Getter
        @Builder
        static class Person {
            private int id;
            private String name;
        }
    }

    /*
    This is the "web app" controller that returns an "app", which will make ajax calls to the api.
    I want this route to be secured, but instead of just returning a 401, I want to start the
    OAuth login process by sending the user to my OAuth Server
     */
    @Controller
    protected static class WebAppController {

        @RequestMapping("/")
        public String webapp() {
            return "index";
        }

        // this should bypass security because it starts with "public"
        @RequestMapping("/public")
        public String publicPage() {
            return "public";
        }

    }

}
java spring-boot spring-security-oauth2
2个回答
0
投票

如果要使用不同的身份验证机制处理应用程序的不同部分,可以创建扩展WebSecurityConfigurerAdapter的其他配置类,并在那里指定安全性约束。

在调用.authorizeRequests()之前,请确保在AntMatcher中指定应将安全配置应用于的URL。见下面的代码。

您可以使用@Order注释设置安全配置的顺序。

HTTP基本身份验证示例

@Configuration
@Order(2) //will be applied after @Order(1), etc...
protected AnotherSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
       http
            .antMatcher("/api/**") //apply only to api endpoints
            .authorizeRequests()
            .antMatchers("/api/admin/**").hasRole("ADMIN")
            .and()
            .httpBasic(); //set to basic auth
    }
}

0
投票

试试这个:

    protected void configure(HttpSecurity http) throws Exception {
        http
....
        .and()
            .exceptionHandling().authenticationEntryPoint(entryPoint())
....
    }

    private AuthenticationEntryPoint entryPoint() {
        return new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                //your code here - can key off of the request
            }
        };
    }
© www.soinside.com 2019 - 2024. All rights reserved.