通过密钥克隆的Spring应用程序基本身份验证 [英] Spring app basic auth over keycloack

查看:61
本文介绍了通过密钥克隆的Spring应用程序基本身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要向我的Spring Boot(MVC)应用添加身份验证.身份验证提供程序是通过OpenID进行的密钥隐藏.隐式和授权代码授予都被禁用,因此我被资源所有者凭证授予所困扰.我要实现的是针对未授权用户的基本身份验证提示.以此方式检索的凭证应用于从密钥斗篷中获取令牌和用户信息,以供Spring Security进一步使用.每次请求时都应检查令牌.

I need to add auth to my spring boot (MVC) app. Auth provider is keycloak via OpenID. Both Implicit and Authorization Code grants are disabled, so I am stuck with Resource owner credentials grant. What I want to achieve is basic auth prompt for unauthorized users. Credentials retrieved that way should be used to get token and user information from keycloak for its further usage by spring security. The token should be checked on each request.

我发现的大多数示例都使用org.keycloak:keycloak-spring-boot-starter的重定向功能.尽管我发现enable-basic-auth 此处,它对我不起作用.我知道我必须使用keycloak.bearer-only=true关闭重定向,但是它可以正常工作,而不是重定向,它会为未授权用户返回401.

Most examples I've found are using the redirect feature of org.keycloak:keycloak-spring-boot-starter. Though I've found enable-basic-auth here, It's not working for me. I am aware that I must use keycloak.bearer-only=true to turn off redirects, but it works so instead of redirecting it returns 401 for unauthorized users.

我的安全配置:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().permitAll();
    }
}

我的keycloak属性(我不使用占位符,只是为了安全起见):

My keycloak properties (I don't use placeholders, it's just for the sake of security):

keycloak.auth-server-url=https://${keycloak.host}/auth/
keycloak.realm=master
keycloak.resource=${client.name}
keycloak.enable-basic-auth=true
keycloak.credentials.secret=${client.secret}

很抱歉提出一般问题.我主要使用jdbcAuthentication,这是我第一次使用Identity Management软件.

Sorry for the general question. I've mostly used jdbcAuthentication and it's my first experience with Identity Management software.

推荐答案

这是一种通过具有资源所有者密码凭据流的keycloak openid向您的应用程序添加基本身份验证的方法.

Here is one way to add basic auth to your application over keycloak openid with Resource owner password credentials flow.

首先,您需要将其添加到pom.xml:

First of all you'll need to add this to pom.xml:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.keycloak.bom</groupId>
            <artifactId>keycloak-adapter-bom</artifactId>
            <version>4.2.0.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

...

<dependencies>
...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
        </dependency>
...
</dependencies>

添加keycloak服务器属性:

Add keycloak server properties:

keycloak.auth-server-url=https://${keycloak.host}/auth/
keycloak.realm=master
keycloak.resource=${client.name}
keycloak.credentials.secret=${client.secret}
keycloak.enable-basic-auth=true
keycloak.bearer-only=true

enable-basic-auth实际上负责启用资源所有者密码凭据流.因此,每次您使用基本授权BasicAuthRequestAuthenticator发送请求时,都会从keycloak请求令牌.需要bearer-only来关闭访问代码流.每次您在没有基本授权(和外部授权会话)的情况下请求对安全资源的请求时,您都将被重定向到keycloak服务器-我们不希望这样.使用bearer-only,您将获得401.

enable-basic-auth is actually responsible for enabling resource owner password credentials flow. So, every time you'll send request with Basic Authorization BasicAuthRequestAuthenticator will request token from keycloak. bearer-only is needed to turn off access code flow. Every time you'd make a request to secured resource without basic authorization (and outside authotized session) you'd get redirected to keycloak server - we don't want that. With bearer-only you'll get 401.

最后一步是添加安全配置:

And last step is adding security configuration:

@Configuration
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
@EnableWebSecurity
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Bean
    public KeycloakAuthenticationProvider authenticationProvider() {
        KeycloakAuthenticationProvider provider = new KeycloakAuthenticationProvider();
        provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        return provider;
    }

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
                    response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\"");
                    response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
                })
                .and()
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .anyRequest().permitAll();
    }
}

这里最有趣的部分是这样:

Most interesting part here is this:

        .exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
            response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\"");
            response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
        })

标准密钥斗篷AuthenticationEntryPoint实现将授权失败的情况下将WWW-Authenticate标头设置为String.format("Bearer realm=\"%s\"", realm).我需要将其设置为Basic realm="Restricted Content"以便弹出基本身份验证提示.如果要避免使用此提示(要添加自己的登录表单),请删除此部分.

Standard keycloak AuthenticationEntryPoint implementation is setting WWW-Authenticate header to String.format("Bearer realm=\"%s\"", realm) in case of authorization failure. I need it to be set to Basic realm="Restricted Content" for the basic auth prompt to pop up. If you want to avoid using this prompt (you want to add your own login form) - remove this part.

这篇关于通过密钥克隆的Spring应用程序基本身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆