복붙노트

[SPRING] Oauth2 : 잘못된 액세스 토큰

SPRING

Oauth2 : 잘못된 액세스 토큰

oauth2 및 스프링 보안을 구현하는 웹 응용 프로그램이 있습니다. 또한 내 웹 응용 프로그램의 일부 보호 된 리소스에 액세스 할 수있는 모바일 웹 응용 프로그램 버전이 있습니다. 내 토큰 URL에 액세스하면 액세스 토큰, 새로 고침 토큰, token_type, expires_in을 제공합니다. 나는 안드로이드가 접근 할 수있는 방법이있다.

그래서 이것은 액세스 토큰을 얻는 URL입니다 :

http://localhost:8080/LEAVE/oauth/token?scope=read,write,trust&grant_type=password&client_id=testclient&client_secret=testsecret&username=john&password=smith

그리고 그것은 저에게 이것을줍니다 :

{
    "access_token": "23ac9377-6de7-47b7-aab9-8aebc9c499d4",
    "token_type": "bearer",
    "refresh_token": "e8e0238c-a98e-4be3-93a9-fbe24bcf6e1d",
    "expires_in": 119,
    "scope": "read,write,trust"
}

이제 보호 된 리소스에 액세스하십시오.

http://localhost:8080/LEAVE/api/users?access_token=23ac9377-6de7-47b7-aab9-8aebc9c499d4

이 URL을 호출하면 다음과 같은 오류가 발생합니다.

{
    "error": "invalid_token",
    "error_description": "Invalid access token: 23ac9377-6de7-47b7-aab9-8 aebc9c499d4"
}

보호되는 클래스 :

@Scope("session")
@RequestMapping("/api/users")
@Component("ParParkingRequestComponent")
public class LeaveComponentImpl implements LeaveComponent {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    @ResponseBody
    public String test(){
        return "Yes It's working";
    }

다음은 spring-security.xml입니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 
                    http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/security
                    http://www.springframework.org/schema/security/spring-security-3.1.xsd">


<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
    authentication-manager-ref="clientAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request 
        parameters -->
    <custom-filter ref="clientCredentialsTokenEndpointFilter"
        after="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>


<!-- This is where we tells spring security what URL should be protected 
    and what roles have access to them -->
<http pattern="/api/**" create-session="never"
    entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager"
    xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/api/**" access="ROLE_APP" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="test" />
</bean>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="test/client" />
    <property name="typeName" value="Basic" />
</bean>

<bean id="oauthAccessDeniedHandler"
    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<bean id="clientCredentialsTokenEndpointFilter"
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
    xmlns="http://www.springframework.org/schema/beans">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <bean class="org.springframework.security.access.vote.RoleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

<authentication-manager id="clientAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>

<bean id="clientDetailsUserService"
    class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <constructor-arg ref="clientDetails" />
</bean>


<!-- This defined token store, we have used inmemory tokenstore for now 
    but this can be changed to a user defined one -->
<bean id="tokenStore"
    class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />


<!-- This is where we defined token based configurations, token validity 
    and other things -->
<bean id="tokenServices"
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="true" />
    <property name="accessTokenValiditySeconds" value="120" />
    <property name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="userApprovalHandler"
    class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
    <property name="tokenServices" ref="tokenServices" />
</bean>

<oauth:authorization-server
    client-details-service-ref="clientDetails" token-services-ref="tokenServices"
    user-approval-handler-ref="userApprovalHandler">
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password />
</oauth:authorization-server>


<oauth:resource-server id="resourceServerFilter"
    resource-id="test" token-services-ref="tokenServices" />

<oauth:client-details-service id="clientDetails">
    <!-- client -->
    <oauth:client client-id="restapp"
        authorized-grant-types="authorization_code,client_credentials"
        authorities="ROLE_APP" scope="read,write,trust" secret="secret" />

    <oauth:client client-id="restapp"
        authorized-grant-types="password,authorization_code,refresh_token,implicit"
        secret="restapp" authorities="ROLE_APP" />

</oauth:client-details-service>

<security:global-method-security
    pre-post-annotations="enabled" proxy-target-class="true">
    <!--you could also wire in the expression handler up at the layer of the 
        http filters. See https://jira.springsource.org/browse/SEC-1452 -->
    <security:expression-handler ref="oauthExpressionHandler" />
</security:global-method-security>

<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />



<!-- Spring security -->

<!-- <security:global-method-security
    secured-annotations="enabled" />
 -->


<security:http auto-config="false" authentication-manager-ref="authenticationManager" use-expressions="true" >
    <!-- Override default login and logout pages -->
    <security:form-login authentication-failure-handler-ref="failureClass" authentication-success-handler-ref="successClass"
        login-page="/login.xhtml" default-target-url="dashboard.xhtml" />
    <security:logout invalidate-session="true" logout-url="/j_spring_security_logout" success-handler-ref="LogoutAction" />  
    <security:session-management>
        <security:concurrency-control max-sessions="10" error-if-maximum-exceeded="true" />
    </security:session-management>  
    <security:intercept-url pattern="/jsf/**" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/run**" access="isAuthenticated()" />  
    <security:intercept-url pattern="/login.xhtml" access="permitAll" />    
</security:http>

<bean id="successClass" class="com.car.SuccessAction"/>

<bean id="failureClass" class="com.car.FailureAction" >
    <property name="defaultFailureUrl" value="/?login_error=true"/>
</bean>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider user-service-ref="userDetailsService" >
        <security:password-encoder ref="passwordEncoder" hash="sha"/>
    </security:authentication-provider>
</security:authentication-manager>

해결법

    from https://stackoverflow.com/questions/33917207/oauth2-invalid-access-token by cc-by-sa and MIT license