code

Java Spring Security: 401 토큰 OAuth2 엔드포인트에 대해 승인되지 않음

starcafe 2023. 7. 22. 10:18
반응형

Java Spring Security: 401 토큰 OAuth2 엔드포인트에 대해 승인되지 않음

스프링 부트 프로젝트에 상당히 기본적인 설정이 있습니다.API를 보호하기 위해 OAuth2를 설정하려고 하지만 문제가 발생했습니다./oauth/token종점.내게 POST 또는 GET 요청을 하는 중/oauth/token엔드포인트 결과는 다음과 같은 반응을 일으킵니다(포함).401 Unauthorized상태 코드):

{
    "timestamp": "2018-09-17T16:46:59.961+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/oauth/token"
}

권한 부여 서버 구성입니다.

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.PasswordEncoder;
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.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client_id")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(600)
                .refreshTokenValiditySeconds(3600);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(this.tokenStore)
                .userApprovalHandler(this.userApprovalHandler)
                .authenticationManager(this.authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(this.passwordEncoder);
    }
}

이것은 내 리소스 서버 구성입니다.아직 중요한 것은 없습니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(this.tokenStore);
    }
}

마지막으로 표준 웹 보안 구성:

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.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder builder) throws Exception {
        builder.inMemoryAuthentication()
                .withUser("user").password("password").roles("ADMIN")
                .and()
                .withUser("admin").password("password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity security) throws Exception {
        security.csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers("/oauth/token").permitAll();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(8);
    }

    @Bean
    @Autowired
    public UserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
        TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(this.clientDetailsService));
        handler.setClientDetailsService(this.clientDetailsService);

        return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);

        return store;
    }
}

저는 제가 그것을 작동시킬 수 있는지 보기 위해 다른 매치기 패턴을 꽤 많이 만지작거렸지만 운이 없었습니다.루트 컨텍스트 및 서블릿 경로에서 실행 중입니다.http://localhost:8080.

Spring Boot이 실행되고 약간 다른 Endpoint를 맞추려고 하면 출력에 끝점이 매핑되어 404가 예상됩니다.

제가 종점을 정확히 맞추지 못한 것으로 드러났습니다.저는 HTTP POST를 통해 클라이언트 자격 증명을 포함한 모든 데이터를 보내고 있었습니다.

POST http://localhost:8080/oauth/token
...
client_id=client_id&secret=secret&scope=read&grant_type=password&username=user&password=password

클라이언트 자격 증명을 게시하는 대신 HTTP Basic Auth를 사용하여 전송해야 했습니다.

POST http://localhost:8080/oauth/token
Authorization: Basic Y2xpZW50X2lkOnNlY3JldA==
...
scope=read&grant_type=password&username=user&password=password

에서 암호 인코더를 변경해 보십시오.AuthorizationServerConfig이 간단한 인코더로 클래스를 만듭니다(암호를 암호화하지 않습니다).암호화를 사용하여 InMemory 저장소에 클라이언트 암호를 저장하지 않기 때문입니다.

private PasswordEncoder getPasswordEncoder() {
    return new PasswordEncoder() {
        public String encode (CharSequence charSequence) {
            return charSequence.toString();
        }
        public boolean matches(CharSequence charSequence, String s) {
            return true;
        }
    };
}

효과가 있기를 바랍니다.

언급URL : https://stackoverflow.com/questions/52372631/java-spring-security-401-unauthorized-for-token-oauth2-end-point

반응형