【问题标题】:secure spring boot with keycloak doenst return 403带钥匙斗篷的安全弹簧靴不会返回 403
【发布时间】:2021-09-06 11:57:32
【问题描述】:

我正在尝试实现我的第一个 Spring Boot 应用程序,并使用 keycloak 进行保护。我在这两个方面都是新手,但我认为到目前为止我做得还不错。我一直在看各种教程,但我最近使用的是this
因此,我设置了一个正在运行的 spring boot/hibernate 应用程序(目前作为概念证明)。所以,现在我想使用 keycloak 来保护它。我所拥有的是 控制器.java

@Controller // This means that this class is a Controller
@RequestMapping(path="/test") // This means URL's start with /demo (after Application path)
public class MainController {
 

    @Autowired
    GemhMainRepository repository;
    
    @Autowired
    CompaniesRepository gsisCompanies;
    
     @RequestMapping("/protected")
        public String protectedHello() {
           System.out.println("test"); return "Hello World, i was protected";
        }}

Main.java

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })//do not create security credentials. we will use our own
public class Main {

     @Bean
        public KeycloakSpringBootConfigResolver keycloakSpringBootConfigResolver(){
            return new KeycloakSpringBootConfigResolver();
        }
     
    public static void main(String[] args) {
        SpringApplication.run(GsisApi.class, args);
    }
}
    

application.properties

    server.port=8080
        
    spring.jpa.hibernate.ddl-auto=none
        
    spring.datasource.url=jdbc:mysql://sqlHost:3306/Db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    spring.datasource.username=user
    spring.datasource.password=password
    spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    spring.jpa.show-sql=true  
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
    keycloak.auth-server-url=http://localhost:31063/auth
    keycloak.realm=testRealm
    keycloak.resource=test_client
    keycloak.public-client=true
    keycloak.security-constraints[0].authRoles[0]=user
    keycloak.security-constraints[0].securityCollections[0].patterns[0]=/test
    keycloak.principal-attribute=preferred_username

SecurityConfig.java

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider  = keycloakAuthenticationProvider();
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .anyRequest().authenticated()
                ;
    }
    
}

当我从 keycloak 获得令牌时,这似乎工作正常,

curl --data "grant_type=password&client_id=test_client&username=user&password=password&client_secret=xxx" 'http://localhost:31063/auth/realms/testRealm/protocol/openid-connect/token'  

我在运行时确实得到了结果

 curl localhost:8080/test/protected -H "Authorization: bearer xxxxxxx " --insecure

但是当我尝试在没有令牌的情况下使用它时,我什么也得不到。甚至没有我在屏幕上打印的消息。我想我需要得到一个 403 错误,以便通知用户他们必须使用一些令牌。对吗?有什么帮助吗? 谢谢

【问题讨论】:

    标签: java spring-boot keycloak


    【解决方案1】:

    好的,看来我让它工作了。出于某种我无法理解的原因,遵循这些说明似乎可以解决问题。我创建了
    MyAuthenticationEntryPoint.java

    @ControllerAdvice
    public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
      @Override
      public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
          throws IOException, ServletException {
        // 401
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
      }
    
      @ExceptionHandler (value = {AccessDeniedException.class})
      public void commence(HttpServletRequest request, HttpServletResponse response,
          AccessDeniedException accessDeniedException) throws IOException {
        // 403
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authorization Failed : " + accessDeniedException.getMessage());
      }
    
      @ExceptionHandler (value = {Exception.class})
      public void commence(HttpServletRequest request, HttpServletResponse response,
          Exception exception) throws IOException {
         // 500
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error : " + exception.getMessage());
      }
    
    }
    

    并将其添加到我的 SecurityConfig.java

    http.exceptionHandling()
          .authenticationEntryPoint(new MyAuthenticationEntryPoint());
    

    制作

    @KeycloakConfiguration
    public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) {
            KeycloakAuthenticationProvider keycloakAuthenticationProvider  = keycloakAuthenticationProvider();
            auth.authenticationProvider(keycloakAuthenticationProvider);
        }
    
        @Override
        protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
            return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            http.authorizeRequests()
            .antMatchers("/test/health/*").permitAll()
                    .anyRequest().authenticated()
                    ;
          http.exceptionHandling()
          .authenticationEntryPoint(new MyAuthenticationEntryPoint());
        }
    }
    

    也可以通过添加 .antMatchers("/test/health/*").permitAll() 我可以在没有任何凭据的情况下调用健康。
    我对自己正在做的事情不是 100% 有信心。因此,如果您发现不对劲的地方,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2019-08-02
      • 1970-01-01
      • 2018-04-26
      • 2018-02-14
      • 2017-06-01
      相关资源
      最近更新 更多