Spring OAuth2 授权服务器配置详解

这篇具有很好参考价值的文章主要介绍了Spring OAuth2 授权服务器配置详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

配置依赖

首先要创建一个Spring Boot Servlet Web项目,这个不难就不赘述了。集成Spring Authorization Server需要引入:

        <!--  spring security starter 必须  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-authorization-server</artifactId>
        <!--  截至现在版本  -->
            <version>0.2.0</version>
        </dependency>

OAuth2.0 Client客户端需要注册到授权服务器并持久化,Spring Authorization Server提供了JDBC实现,参见JdbcRegisteredClientRepository。为了演示方便这里我采用了H2数据库,需要以下依赖:

        <!--  jdbc 必须引入否则自行实现  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

生产你可以切换到其它关系型数据库,数据库脚本在Spring Authorization Server入门 一文的DEMO中。

Spring Authorization Server配置

接下来是Spring Authorization Server的配置。

过滤器链配置

根据上一文对过滤器链的拆解,我们需要在Spring Security的过滤器链中注入一些特定的过滤器。这些过滤器的配置由OAuth2AuthorizationServerConfigurer<HttpSecurity>来完成。以下为默认的配置:

    void defaultOAuth2AuthorizationServerConfigurer(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
                new OAuth2AuthorizationServerConfigurer<>();
        // TODO 你可以根据需求对authorizationServerConfigurer进行一些个性化配置
        RequestMatcher authorizationServerEndpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();

        // 拦截 授权服务器相关的请求端点
        http.requestMatcher(authorizationServerEndpointsMatcher)
                .authorizeRequests().anyRequest().authenticated().and()
                // 忽略掉相关端点的csrf
                .csrf(csrf -> csrf.ignoringRequestMatchers(authorizationServerEndpointsMatcher))
                // 开启form登录
                .formLogin()
                .and()
                // 应用 授权服务器的配置
                .apply(authorizationServerConfigurer);
    }

你可以调用OAuth2AuthorizationServerConfigurer<HttpSecurity>提供的配置方法进行一些个性化配置。

OAuth2.0客户端信息持久化

这些信息会持久化到数据库,Spring Authorization Server提供了三个DDL脚本。在入门教程的DEMO,H2会自动初始化执行这些DDL脚本,如果你切换到Mysql等数据库,可能需要你自行执行。

客户端配置信息注册

授权服务器要求客户端必须是已经注册的,避免非法的客户端发起授权申请。就像你平常去一些开放平台申请一个ClientIDSecret。下面是定义脚本:

CREATE TABLE oauth2_registered_client
(
    id                            varchar(100)                        NOT NULL,
    client_id                     varchar(100)                        NOT NULL,
    client_id_issued_at           timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
    client_secret                 varchar(200)                        NULL,
    client_secret_expires_at      timestamp                           NULL,
    client_name                   varchar(200)                        NOT NULL,
    client_authentication_methods varchar(1000)                       NOT NULL,
    authorization_grant_types     varchar(1000)                       NOT NULL,
    redirect_uris                 varchar(1000)                       NULL,
    scopes                        varchar(1000)                       NOT NULL,
    client_settings               varchar(2000)                       NOT NULL,
    token_settings                varchar(2000)                       NOT NULL,
    PRIMARY KEY (id)
);

对应的Java类为RegisteredClient:

public class RegisteredClient implements Serializable {
 private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
 private String id;
 private String clientId;
 private Instant clientIdIssuedAt;
 private String clientSecret;
 private Instant clientSecretExpiresAt;
 private String clientName;
 private Set<ClientAuthenticationMethod> clientAuthenticationMethods;
 private Set<AuthorizationGrantType> authorizationGrantTypes;
 private Set<String> redirectUris;
 private Set<String> scopes;
 private ClientSettings clientSettings;
 private TokenSettings tokenSettings;
    
    // 省略
}

定义一个客户端可以通过下面的Builder方法实现:

        RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
//               唯一的客户端ID和密码
                .clientId("felord-client")
                .clientSecret("secret")
//                名称 可不定义
                .clientName("felord")
//                授权方法
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
//                授权类型
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
//                回调地址名单,不在此列将被拒绝 而且只能使用IP或者域名  不能使用 localhost
                .redirectUri("http://127.0.0.1:8080/login/oauth2/code/felord-oidc")
                .redirectUri("http://127.0.0.1:8080/authorized")
                .redirectUri("http://127.0.0.1:8080/foo/bar")
                .redirectUri("https://baidu.com")
//                OIDC支持
                .scope(OidcScopes.OPENID)
//                其它Scope
                .scope("message.read")
                .scope("message.write")
//                JWT的配置项 包括TTL  是否复用refreshToken等等
                .tokenSettings(TokenSettings.builder().build())
//                配置客户端相关的配置项,包括验证密钥或者 是否需要授权页面
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                .build();

持久化到数据库的RegisteredClient用JSON表示为:

  {
    "id": "658cd010-4d8c-4824-a8c7-a86b642299af",
    "client_id": "felord-client",
    "client_id_issued_at": "2021-11-11 18:01:09",
    "client_secret": "{bcrypt}$2a$10$XKZ8iUckDcdQWnqw682zV.DVyGuov8Sywx1KyAn4tySsw.Jtltg0.",
    "client_secret_expires_at": null,
    "client_name": "felord",
    "client_authentication_methods": "client_secret_basic",
    "authorization_grant_types": "refresh_token,client_credentials,authorization_code",
    "redirect_uris": "http://127.0.0.1:8080/foo/bar,http://127.0.0.1:8080/authorized,http://127.0.0.1:8080/login/oauth2/code/felord-oidc,https://baidu.com",
    "scopes": "openid,message.read,message.write",
    "client_settings": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-proof-key\":false,\"settings.client.require-authorization-consent\":true}",
    "token_settings": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.token.reuse-refresh-tokens\":true,\"settings.token.id-token-signature-algorithm\":[\"org.springframework.security.oauth2.jose.jws.SignatureAlgorithm\",\"RS256\"],\"settings.token.access-token-time-to-live\":[\"java.time.Duration\",300.000000000],\"settings.token.refresh-token-time-to-live\":[\"java.time.Duration\",3600.000000000]}"
  }

注意上面的配置和你OAuth2.0客户端应用的配置息息相关。

既然持久化了,那自然需要操作该表的JDBC服务接口了,这个接口为RegisteredClientRepository。我们需要声明一个实现为Spring Bean,这里选择基于JDBC的实现:

   @Bean
   public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
        return new JdbcRegisteredClientRepository(jdbcTemplate);
     }

别忘记调用save(RegisteredClient)方法把需要注册的客户端信息持久化。

该实现依赖spring-boot-starter-jdbc类库,你也可以闲得慌使用Mybatis进行实现。

OAuth2授权信息持久化

记录授权的资源拥有者(Resource Owner)对某个客户端的某次授权记录。对应的Java类为OAuth2Authorization。下面是定义脚本:

CREATE TABLE oauth2_authorization
(
    id                            varchar(100)  NOT NULL,
    registered_client_id          varchar(100)  NOT NULL,
    principal_name                varchar(200)  NOT NULL,
    authorization_grant_type      varchar(100)  NOT NULL,
    attributes                    varchar(4000) NULL,
    state                         varchar(500)  NULL,
    authorization_code_value      blob          NULL,
    `authorization_code_issued_at`  timestamp     NULL,
    authorization_code_expires_at timestamp     NULL,
    authorization_code_metadata   varchar(2000) NULL,
    access_token_value            blob          NULL,
    access_token_issued_at        timestamp     NULL,
    access_token_expires_at       timestamp     NULL,
    access_token_metadata         varchar(2000) NULL,
    access_token_type             varchar(100)  NULL,
    access_token_scopes           varchar(1000) NULL,
    oidc_id_token_value           blob          NULL,
    oidc_id_token_issued_at       timestamp     NULL,
    oidc_id_token_expires_at      timestamp     NULL,
    oidc_id_token_metadata        varchar(2000) NULL,
    refresh_token_value           blob          NULL,
    refresh_token_issued_at       timestamp     NULL,
    refresh_token_expires_at      timestamp     NULL,
    refresh_token_metadata        varchar(2000) NULL,
    PRIMARY KEY (id)
);

这里的机制目前还没有研究,先挖个坑。

同样它也需要一个持久化服务接口OAuth2AuthorizationService并注入Spring IoC

/**
 * 管理OAuth2授权信息服务
 *
 * @param jdbcTemplate               the jdbc template
 * @param registeredClientRepository the registered client repository
 * @return the o auth 2 authorization service
 */
@Bean
public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate,
                                                       RegisteredClientRepository registeredClientRepository) {
    return new JdbcOAuth2AuthorizationService(jdbcTemplate, 
            registeredClientRepository);
}

持久化到数据库的OAuth2Authorization用JSON表示为:

  {
    "id": "aa2f6e7d-d9b9-4360-91ef-118cbb6d4b09",
    "registered_client_id": "658cd010-4d8c-4824-a8c7-a86b642299af",
    "principal_name": "felord",
    "authorization_grant_type": "authorization_code",
    "attributes": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest\":{\"@class\":\"org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest\",\"authorizationUri\":\"http://localhost:9000/oauth2/authorize\",\"authorizationGrantType\":{\"value\":\"authorization_code\"},\"responseType\":{\"value\":\"code\"},\"clientId\":\"felord-client\",\"redirectUri\":\"http://127.0.0.1:8080/foo/bar\",\"scopes\":[\"java.util.Collections$UnmodifiableSet\",[\"message.read\",\"message.write\"]],\"state\":\"9gTcVNXgV8Pn_Ron3bkFb6M92AYCodeWKoEd6xxaiUg=\",\"additionalParameters\":{\"@class\":\"java.util.Collections$UnmodifiableMap\"},\"authorizationRequestUri\":\"http://localhost:9000/oauth2/authorize?response_type=code&client_id=felord-client&scope=message.read%20message.write&state=9gTcVNXgV8Pn_Ron3bkFb6M92AYCodeWKoEd6xxaiUg%3D&redirect_uri=http://127.0.0.1:8080/foo/bar\",\"attributes\":{\"@class\":\"java.util.Collections$UnmodifiableMap\"}},\"java.security.Principal\":{\"@class\":\"org.springframework.security.authentication.UsernamePasswordAuthenticationToken\",\"authorities\":[\"java.util.Collections$UnmodifiableRandomAccessList\",[{\"@class\":\"org.springframework.security.core.authority.SimpleGrantedAuthority\",\"authority\":\"ROLE_USER\"}]],\"details\":{\"@class\":\"org.springframework.security.web.authentication.WebAuthenticationDetails\",\"remoteAddress\":\"0:0:0:0:0:0:0:1\",\"sessionId\":\"FD624F1AD55A2418CC9815A86AA32696\"},\"authenticated\":true,\"principal\":{\"@class\":\"org.springframework.security.core.userdetails.User\",\"password\":null,\"username\":\"felord\",\"authorities\":[\"java.util.Collections$UnmodifiableSet\",[{\"@class\":\"org.springframework.security.core.authority.SimpleGrantedAuthority\",\"authority\":\"ROLE_USER\"}]],\"accountNonExpired\":true,\"accountNonLocked\":true,\"credentialsNonExpired\":true,\"enabled\":true},\"credentials\":null},\"org.springframework.security.oauth2.server.authorization.OAuth2Authorization.AUTHORIZED_SCOPE\":[\"java.util.Collections$UnmodifiableSet\",[\"message.read\",\"message.write\"]]}",
    "state": null,
    "authorization_code_value": "EZFxDcsKoaGtyqRTS0oNMg85EcVcyLdVssuD3SV-o0FvNXsSTRjTmCdu0ZPZnVIQ7K4TTSzrvLwBqoRXOigo_dWVNeqE44LjHHL_KtujM_Mxz8hLZgGhtfipvTdpWWR1",
    "authorization_code_issued_at": "2021-11-11 18:44:45",
    "authorization_code_expires_at": "2021-11-11 18:49:45",
    "authorization_code_metadata": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"metadata.token.invalidated\":true}",
    "access_token_value": "eyJ4NXQjUzI1NiI6IlZGR1F4Q21nSEloX2dhRi13UGIxeEM5b0tBMXc1bGEwRUZtcXFQTXJxbXciLCJraWQiOiJmZWxvcmRjbiIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJmZWxvcmQiLCJhdWQiOiJmZWxvcmQtY2xpZW50IiwibmJmIjoxNjM2NjI3NDg0LCJzY29wZSI6WyJtZXNzYWdlLnJlYWQiLCJtZXNzYWdlLndyaXRlIl0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNjM2NjI3Nzg0LCJpYXQiOjE2MzY2Mjc0ODR9.CFzye9oIh8-ZMpyp9XoIXIQLnj2Sn17yZ9bgn7NYAbrp2hRq-Io_Se2SJpSEMa_Ce44aOGmcLTmIOILYUxlU08QCtHgr4UfCZttzroQhEn3Qui7fixBMprPYqxmu2KL5G_l3q5EWyh4G0ilHpByCBDeBGAl7FpaxSDlelnBfNGs9q6nJCs7aC40U_YPBRLoCBLVK1Y8t8kQvNu8NqCkS5D5DZAogpmlVg7jSIPz1UXVIh7iDTTQ1wJl6rZ1E87E0UroX4eSuYfMQ351y65IUlB14hvKhu03yDLTiVKtujOo3m0DAkJTbk3ZkFZEmDf4N3Yn-ktU7cyswQWa1bKf3og",
    "access_token_issued_at": "2021-11-11 18:44:45",
    "access_token_expires_at": "2021-11-11 18:49:45",
    "access_token_metadata": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"metadata.token.claims\":{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"sub\":\"felord\",\"aud\":[\"java.util.Collections$SingletonList\",[\"felord-client\"]],\"nbf\":[\"java.time.Instant\",1636627484.674000000],\"scope\":[\"java.util.Collections$UnmodifiableSet\",[\"message.read\",\"message.write\"]],\"iss\":[\"java.net.URL\",\"http://localhost:9000\"],\"exp\":[\"java.time.Instant\",1636627784.674000000],\"iat\":[\"java.time.Instant\",1636627484.674000000]},\"metadata.token.invalidated\":false}",
    "access_token_type": "Bearer",
    "access_token_scopes": "message.read,message.write",
    "oidc_id_token_value": null,
    "oidc_id_token_issued_at": null,
    "oidc_id_token_expires_at": null,
    "oidc_id_token_metadata": null,
    "refresh_token_value": "hbD9dVMpu855FhDDOYapwsQSx8zO9iPX5LUZKeXWzUcbE2rgYRV-sgXl5vGwyByLNljcqVyK9Pgquzbcoe6dkt0_yPQPJfxLY8ezEQ-QREBjxNYqecd6OI9SHMQkBObG",
    "refresh_token_issued_at": "2021-11-11 18:44:45",
    "refresh_token_expires_at": "2021-11-11 19:44:45",
    "refresh_token_metadata": "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"metadata.token.invalidated\":false}"
  }

存储的东西还是比较全的,甚至把Java类都序列化了。

确认授权持久化

资源拥有者(Resource Owner)对授权的确认信息OAuth2AuthorizationConsent的持久化,这个比较简单。下面是定义脚本:

CREATE TABLE oauth2_authorization_consent
(
    registered_client_id varchar(100)  NOT NULL,
    principal_name       varchar(200)  NOT NULL,
    authorities          varchar(1000) NOT NULL,
    PRIMARY KEY (registered_client_id, principal_name)
);

对应的持久化服务接口为OAuth2AuthorizationConsentService,也要注入Spring IoC:

@Bean
public OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, 
                                                                     RegisteredClientRepository registeredClientRepository) {
    return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
}

持久化到数据库的OAuth2AuthorizationConsent用JSON表示为:

  {
    "registered_client_id": "658cd010-4d8c-4824-a8c7-a86b642299af",
    "principal_name": "felord",
    "authorities": "SCOPE_message.read,SCOPE_message.write"
  }

JWK

JWK全称JSON Web Key,是一个将加密的密钥用JSON对象描述的规范,和JWT一样是JOSE规范的重要组成部分。规范的详细定义可参考JWK文档。JWK参考示例:

{
    "keys": [
        {
            "kty": "RSA",
            "x5t#S256": "VFGQxCmgHIh_gaF-wPb1xC9oKA1w5la0EFmqqPMrqmw",
            "e": "AQAB",
            "kid": "felordcn",
            "x5c": [
"MIIDczCCAlugAwIBAgIEURwmYzANBgkqhkiG9w0BAQsFADBqMQ0wCwYDVQQGEwQoY24pMQ0wCwYDVQQIEwQoaG4pMQ0wCwYDVQQHEwQoenopMRMwEQYDVQQKEwooZmVsb3JkY24pMRMwEQYDVQQLEwooZmVsb3JkY24pMREwDwYDVQQDEwgoRmVsb3JkKTAeFw0yMTEwMTgwNDUwMTRaFw0yMjEwMTgwNDUwMTRaMGoxDTALBgNVBAYTBChjbikxDTALBgNVBAgTBChobikxDTALBgNVBAcTBCh6eikxEzARBgNVBAoTCihmZWxvcmRjbikxEzARBgNVBAsTCihmZWxvcmRjbikxETAPBgNVBAMTCChGZWxvcmQpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgo0TPk1td7iROmmLcGbOsZ2F68kTertDwRyk+leqBl+qyJAkjoVgVaCRRQHZmvu/YGp93vOaEd/zFdVj/rFvMXmwBxgYPOeSG0bHkYtFBaUiLf1vhW5lyiPHcGide3uw1p+il3JNiOpcnLCbAKZgzm4qaugeuOD02/M0YcMW2Jqg3SUWpC+9vu9yt5dVc1xpmpwEAamKzvynI3Zxl44ddlA8RRAS6kV0OUcKbEG63G3yZ4MHnhrFrZDuvlwfSSgn0wFOC/b6mJ+bUxByMAXKD0d4DS2B2mVl7RO5AzL4SFcqtZZE3Drtcli67bsENyOQeoTVaKO6gu5PEEFlQ7pHKwIDAQABoyEwHzAdBgNVHQ4EFgQUqbLZ76DtdEEpTZUcgP7LsdGk8/AwDQYJKoZIhvcNAQELBQADggEBAEzfhi6/B00NxSPKAYJea/0MIyHr4X8Ue6Du+xl2q0UFzSkyIiMcPNmOYW5L1PWGjxR5IIiUgxKI5bEvhLkHhkMV+GRQSPKJXeC3szHdoZ3fXDZnuC0I88a1YDsvzuVhyjLL/n5lETRT4QWo5LsAj5v7AX+p46HM0iqSyTptafm2wheEosFA3ro4+vEDRaMrKLY1KdJuvvrrQIRpplhB/JbncmjWrEEvICSLEXm+kdGFgWNXkNxF0PhTLyPu3tEb2xLmjFltALwi3KPUGv9zVjxb7KyYiMnVsOPnwpDLOyREM9j4RLDiwf0tsCqPqltVExvFZouoL26fhcozfcrqC70="
            ],
            "n": "go0TPk1td7iROmmLcGbOsZ2F68kTertDwRyk-leqBl-qyJAkjoVgVaCRRQHZmvu_YGp93vOaEd_zFdVj_rFvMXmwBxgYPOeSG0bHkYtFBaUiLf1vhW5lyiPHcGide3uw1p-il3JNiOpcnLCbAKZgzm4qaugeuOD02_M0YcMW2Jqg3SUWpC-9vu9yt5dVc1xpmpwEAamKzvynI3Zxl44ddlA8RRAS6kV0OUcKbEG63G3yZ4MHnhrFrZDuvlwfSSgn0wFOC_b6mJ-bUxByMAXKD0d4DS2B2mVl7RO5AzL4SFcqtZZE3Drtcli67bsENyOQeoTVaKO6gu5PEEFlQ7pHKw"
        }
    ]
}

JWK的意义在于生成JWT和提供JWK端点给OAuth2.0资源服务器解码校验JWT

公私钥

JWK会涉及到加密算法,这里使用RSASHA256算法来作为加密算法,并通过Keytool工具来生成.jks公私钥证书文件。当然你也可以通过openssl来生成pkcs12格式的证书。在Spring Security实战干货中已经对生成的方法进行了说明,这里不再赘述。

JWKSource

由于Spring Security的JOSE实现依赖的是nimbus-jose-jwt,所以这里只需要我们实现JWKSource <C extends SecurityContext>并注入Spring IoC即可。相关代码如下:

    /**
     * 加载JWK资源
     *
     * @return the jwk source
     */
    @SneakyThrows
    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        //TODO 这里优化到配置
        // 证书的路径
        String path = "felordcn.jks";
        // 证书别名
        String alias = "felordcn";
        // keystore 密码
        String pass = "123456";

        ClassPathResource resource = new ClassPathResource(path);
        KeyStore jks = KeyStore.getInstance("jks");
//        KeyStore pkcs12 = KeyStore.getInstance("pkcs12");
        char[] pin = pass.toCharArray();
        jks.load(resource.getInputStream(), pin);
        RSAKey rsaKey = RSAKey.load(jks, alias, pin);

        JWKSet jwkSet = new JWKSet(rsaKey);
        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    }

授权服务器元信息配置

客户端信息RegisteredClient包含了Token的配置项TokenSettings和客户端配置项ClientSettings。授权服务器本身也提供了一个配置工具来配置其元信息,大多数我们都使用默认配置即可,唯一需要配置的其实只有授权服务器的地址issuer,在DEMO中虽然我使用localhost:9000issuer没有什么问题,但是在生产中这个地方应该配置为域名

    /**
     * 配置 OAuth2.0 provider元信息
     *
     * @return the provider settings
     */
    @Bean
    public ProviderSettings providerSettings(@Value("${server.port}") Integer port) {
        //TODO 生产应该使用域名
        return ProviderSettings.builder().issuer("http://localhost:" + port).build();
    }

你可以修改本地的hosts文件试试用域名。

到这里Spring Authorization Server的配置就完成了,但是整个授权服务器的配置还没有完成。

授权服务器安全配置

上面是授权服务器本身的配置,授权服务器本身的安全配置是另外一条过滤器链承担的,我们也要对它进行一些配置,都是常规的Spring Security配置,这里给一个简单的配置,也是DEMO中的配置:

@EnableWebSecurity(debug = true)
public class DefaultSecurityConfig {

    // @formatter:off
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorizeRequests ->
                        authorizeRequests.anyRequest().authenticated()
                )
                .formLogin();
        return http.build();
    }
    // @formatter:on

    /**
     * 在内存中抽象一个Spring Security安全用户{@link User},同时该用户也是Resource Owner;
     * 实际开发中需要持久化到数据库。
     *
     * @return the user details service
     */
// @formatter:off
    @Bean
    UserDetailsService users() {
        UserDetails user = User.builder()
                .username("felord")
                .password("password")
                .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode)
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
    // @formatter:on


    /**
     * 开放一些端点的访问控制。
     *
     * 如果你使用了一些依赖这些端点的程序,比如Consul健康检查;
     * 打开H2数据库web控制台访问控制,方便你查看数据具体看配置文件说明。
     *
     * @return the web security customizer
     */
    @Bean
    WebSecurityCustomizer webSecurityCustomizer() {
        return web -> web.ignoring().antMatchers("/actuator/health","/h2-console/**");
    }
}

到这里一个基于Spring Authorization Server的授权服务器就搭建好了。

解惑

为什么一个项目配置了两个甚至多个SecurityFilterChain?

之所以有两个SecurityFilterChain是因为程序设计要保证职责单一,无论是底层架构还是业务代码,为此HttpSecurity被以基于原型(prototype)的Spring Bean注入Spring IoC。针对本应用中的两条过滤器链,分别是授权服务器的过滤器链和应用安全的过滤器链,它们之间其实互相没有太多联系。

oauth2配置资源服务,spring,服务器,java,程序人生,学习文章来源地址https://www.toymoban.com/news/detail-850288.html

到了这里,关于Spring OAuth2 授权服务器配置详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring cloud、gradle、父子项目、微服务框架搭建---spring secuity oauth2、mysql 授权(九)

    https://preparedata.blog.csdn.net/article/details/120062997 新建两个服务 1.授权服务 端口号:11007 2.资源服务 端口号:11004 资源服务可以是订单服务、用户服务、商品服务等等 当然这两个服务也可以合并到一起, 依次顺序AuthorizationServerConfiguration、ResourceServerConfig、WebSecurityConfiguration;

    2024年02月10日
    浏览(31)
  • Spring Security—OAuth2 客户端认证和授权

    关于 JWT Bearer 客户端认证的进一步详情,请参考OAuth 2.0客户端认证和授权许可的 JSON Web Token (JWT)简介。 JWT Bearer 客户端认证的默认实现是  NimbusJwtClientAuthenticationParametersConverter ,它是一个  Converter ,通过在  client_assertion  参数中添加签名的JSON Web Token(JWS)来定制令牌请求

    2024年02月08日
    浏览(37)
  • Spring Cloud Gateway 整合OAuth2.0 实现统一认证授权

    Spring Cloud Gateway 整合OAuth2.0 实现统一认证授权 GateWay——向其他服务传递参数数据 https://blog.csdn.net/qq_38322527/article/details/126530849 @EnableAuthorizationServer Oauth2ServerConfig 验证签名 网关服务需要RSA的公钥来验证签名是否合法,所以认证服务需要有个接口把公钥暴露出来 接下来搭建网

    2024年02月13日
    浏览(29)
  • SpringCloud整合spring security+ oauth2+Redis实现认证授权

    在微服务构建中,我们一般用一个父工程来通知管理依赖的各种版本号信息。父工程pom文件如下: 在SpringCloud微服务体系中服务注册中心是一个必要的存在,通过注册中心提供服务的注册和发现。具体细节可以查看我之前的博客,这里不再赘述。我们开始构建一个eureka注册中

    2024年02月06日
    浏览(43)
  • B094-人力资源项目-微服务授权&Oauth2

    背景 微服务架构下应用散步在不同的服务器上,不是一个tomcat ,不能再基于Session 不同的服务不同的功能,都要有权限控制,不能再基于Session用Security 微服务权限控制用Redis: 微服务用Redis做权限控制数据不好存 要查Redis, 权限变动时数据库与redis需要同步,redis不好改,如

    2024年02月09日
    浏览(23)
  • oauth2-resource-server授权配置介绍

    当了解这篇文章授权服务器后,对授权服务器有一定的认识,那么授权服务器生成token后,该怎么用呢,这就涉及到资源服务器,现在给大家简单介绍实现过程。 2.1 基于官网配置 首先先配置 issuer-uri ,这里指向是授权服务器的地址 关于过滤器链的配置: 资源服务器将使用

    2024年02月12日
    浏览(23)
  • Spring Security 6.x 系列【50】授权服务器篇之Spring Boot 3.1自动配置

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.10 本系列Spring Security 版本 6.1.0 本系列Spring Authorization Serve 版本 1.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo

    2024年02月08日
    浏览(32)
  • 电商项目part06 微服务网关整合OAuth2.0授权中心

    网关整合 OAuth2.0 有两种思路,一种是授权服务器生成令牌, 所有请求统一在网关层验证,判断权 限等操作;另一种是由各资源服务处理,网关只做请求转发。 比较常用的是第一种,把API网关作 为OAuth2.0的资源服务器角色,实现接入客户端权限拦截、令牌解析并转发当前登录

    2024年02月11日
    浏览(23)
  • Spring Security Oauth2.1 最新版 1.1.0 整合 gateway 完成授权认证(拥抱 springboot 3.1)

    目录 背景 demo地址 版本 Spring Boot 3.1 Spring Authorization Server 1.1.0 基础 spring security OAuth2 模块构成 授权方式 认证方式 集成过程 官方demo 代码集成 依赖 授权服务AuthorizationServerConfig配置 重要组件 测试 查看授权服务配置 访问授权服务 授权 回调 获取 access_token 获取用户信息 个性

    2024年02月08日
    浏览(47)
  • Spring Security OAuth2详解

    spring security oauth2框架即spring security + OAuth2,spring security上一篇文章已经讲过,接下来讲讲OAuth2,它是行业标准的授权协议,旨在为开发人员提供简单易用的授权流程;OAuth 定义了四种角色: 资源所有者:能够授予对受保护资源的访问权限的实体,当资源所有者是一个人时,

    2024年02月03日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包