Реализация авторизации и аутентификации клиента oauth2 с использованием источника данных jdb c дает несанкционированный - PullRequest
0 голосов
/ 04 мая 2020

Я реализовал сущность User с CustomUserDetailService, до аутентификации все работает хорошо. Когда я пытался настроить oauth2 для авторизации клиентов. Код работал хорошо для деталей клиента InMemory. Проблема возникла, когда я попытался добавить источник данных JDB c для деталей клиента. Класс сущности для oauth_client_details приведен ниже:

package com.meganos.app.security.auth;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name="oauth_client_details")
public class OauthClientDetails {
    @Id
    @Column(name="client_id")
    private String clientId;

    @Column(name="resource_ids")
    private String resourceIds;

    @Column(name="client_secret")
    private String clientSecret;

    @Column(name="scope")
    private String scope;

    @Column(name="authorized_grant_types")
    private String authorizedGrantTypes;

    @Column(name="web_server_redirect_uri")
    private String webServerRedirectUri;

    @Column(name="authorities")
    private String authorities;

    @Column(name="access_token_validity", length=11)
    private Integer accessTokenValidity;

    @Column(name="refresh_token_validity", length=11)
    private Integer refreshTokenValidity;

    @Column(name="additional_information", length=4096)
    private String additionalInformation;

    @Column(name="autoapprove", columnDefinition = "TINYINT(4)")
    private String autoapprove;

    @Column(name="uuid")
    private String uuid;

    @Column
    private Date created;

    @Column(columnDefinition ="boolean default true")
    private Boolean enabled;

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getResourceIds() {
        return resourceIds;
    }

    public void setResourceIds(String resourceIds) {
        this.resourceIds = resourceIds;
    }

    public String getClientSecret() {
        return clientSecret;
    }

    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getAuthorizedGrantTypes() {
        return authorizedGrantTypes;
    }

    public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
        this.authorizedGrantTypes = authorizedGrantTypes;
    }

    public String getWebServerRedirectUri() {
        return webServerRedirectUri;
    }

    public void setWebServerRedirectUri(String webServerRedirectUri) {
        this.webServerRedirectUri = webServerRedirectUri;
    }

    public String getAuthorities() {
        return authorities;
    }

    public void setAuthorities(String authorities) {
        this.authorities = authorities;
    }

    public Integer getAccessTokenValidity() {
        return accessTokenValidity;
    }

    public void setAccessTokenValidity(Integer accessTokenValidity) {
        this.accessTokenValidity = accessTokenValidity;
    }

    public Integer getRefreshTokenValidity() {
        return refreshTokenValidity;
    }

    public void setRefreshTokenValidity(Integer refreshTokenValidity) {
        this.refreshTokenValidity = refreshTokenValidity;
    }

    public String getAdditionalInformation() {
        return additionalInformation;
    }

    public void setAdditionalInformation(String additionalInformation) {
        this.additionalInformation = additionalInformation;
    }

    public String getAutoapprove() {
        return autoapprove;
    }

    public void setAutoapprove(String autoapprove) {
        this.autoapprove = autoapprove;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
}

Код класса моего сервера авторизации находится здесь:

package com.meganos.app.security.config;

import com.meganos.app.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

import javax.sql.DataSource;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(NoOpPasswordEncoder.getInstance())
                .checkTokenAccess("permitAll()")
                .tokenKeyAccess("permitAll()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource)
//                .inMemory()
                .withClient("admin_app")
                .secret("secret")
                .scopes("1")
                .autoApprove(true)
                .authorizedGrantTypes("password","authorization_code", "refresh_token", "client_credentials")
                .resourceIds()
                .and()
                .build();
//        JdbcClientDetailsService jdbcClientDetailsService=new JdbcClientDetailsService(dataSource);
//        clients.withClientDetails(jdbcClientDetailsService);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .tokenStore(new InMemoryTokenStore())
//                .approvalStoreDisabled()
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }
}

У меня возникают следующие проблемы:

  1. Первая и главная проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь использовать clients.inMemory().withClients().. при настройке ClientDetailsServiceConfigurer, он работает гладко, он хорошо генерирует токен и справедливо авторизует запросы. Но когда я попытался добавить clients.jdbc(datasource).withClients().. и попытался сгенерировать токен, используя Почтальон, как показано: Postman Post Request for token generation

с базой c oauth с использованием введенных данных клиента в построении клиента детали: Entering the basic oauth in Postman, если дает несанкционированный доступ к этому URL, как это:

{
    "timestamp": "2020-05-04T08:21:09.223+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/oauth/token"
}

Вторая проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытался ввести область действия в какой-либо строковой форме, такой как (чтение, запись) как:

clients.jdb c (dataSource) .inMemory () .withClient ("admin_app") .secret ("secret") .scopes ("read") .autoApprove (true) .authorizedGrantTypes ("пароль", "код авторизации", "refresh_token", "" client_credentials ") .resourceIds () .and () .build ();

выдает следующую ошибку при сборке клиентов и сохранении в базе данных:

Data conversion error converting "'read' (OAUTH_CLIENT_DETAILS: ""AUTOAPPROVE"" TINYINT)"; SQL statement:

Код моего класса AuthenticationServerConfig приведен ниже:

package com.meganos.app.security.config;

import com.meganos.app.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AuthenticationServerConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Bean
    public DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider();
        authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder(11));
        authenticationProvider.setUserDetailsService(customUserDetailsService);
        authenticationProvider.setAuthoritiesMapper(grantedAuthoritiesMapper());

        return authenticationProvider;
    }

    @Bean
    public GrantedAuthoritiesMapper grantedAuthoritiesMapper(){
        SimpleAuthorityMapper authorityMapper=new SimpleAuthorityMapper();
        authorityMapper.setConvertToUpperCase(true);
        authorityMapper.setDefaultAuthority("USER");
        return authorityMapper;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .httpBasic()
                .and()
                .logout().invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
        web.ignoring()
                .antMatchers("/", "/index", "/css/*", "/js/*", "/test/unsecured", "/oauth/token/*")
                .antMatchers("/h2-console", "/h2-console/*");
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

Я видел много вопросов, подобных этому, в stackoverflow и пытался решить свои проблемы, используя их, но я не получил положительного ответа после попытки всего. Я ищу руководство для экспертов, заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...