tutorial seguridad español spring-security-oauth2

spring-security-oauth2 - seguridad - spring security 4 tutorial español



¿Cómo cambiar la seguridad de Spring o un punto final de token predeterminado? (4)

Con la versión 2.0.5.RELEASE o superior de spring-security-oauth2

En una línea en la configuración basada en java, probada y funciona bien, de alguna manera está anulando el valor de RequestMapping de la clase TokenEndpoint.

@Configuration @EnableAuthorizationServer protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .pathMapping("/oauth/token", "<your custom endpoint>") } }

Tenemos una aplicación basada en la seguridad oauth2 de Spring. Todo funciona bien. Pero no puedo cambiar el punto final del token predeterminado de "/ oauth / token" a "/ external / oauth / token".

Mi spring-servlet.xml

<http pattern="/external/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" use-expressions="true" xmlns="http://www.springframework.org/schema/security"> <intercept-url pattern="/external/oauth/token" access="isFullyAuthenticated()" /> <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> <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" token-endpoint-url="/external/oauth/token"> <oauth:authorization-code /> <oauth:implicit /> <oauth:refresh-token /> <oauth:client-credentials /> <oauth:password /> </oauth:authorization-server>

Pero el resultado cuando accedo a este punto final es

{ error: "unauthorized" error_description: "An Authentication object was not found in the SecurityContext" }

¿Me estoy perdiendo algo? Por favor recomiende.


Lo estás haciendo más difícil de lo que debería ser, ¡en realidad es muy simple! (Tenga en cuenta que estoy utilizando "oauth2:" en lugar de "oauth:" como etiqueta XML)

  1. Ve a tu security-context.xml

  2. Busque "oauth2: permission-server" en el archivo anterior.

    <oauth2:authorization-server client-details-service-ref="someService" request-validator-ref="someScopeRequestValidator" token-services-ref="someTokenServices" >

  3. Simplemente agregue token-endpoint-url="/oauth/whatever_you_like"

    <oauth2:authorization-server client-details-service-ref="someService" request-validator-ref="someScopeRequestValidator" token-services-ref="someTokenServices" **token-endpoint-url="/oauth/whatever_you_like"** >


Para personalizar la URL del punto final del token, realice los siguientes pasos.

1) Escriba su propia clase que amplíe la clase ClientCredentialsTokenEndpointFilter y llame al constructor de la clase ClientCredentialsTokenEndpointFilter con el valor "/ external / oauth / token".

super("/external/oauth/token");

2) Conecte su nuevo filtro personalizado en la configuración de seguridad.

Reemplazar

<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />

con

<custom-filter ref="your customize filter" after="BASIC_AUTH_FILTER" />

3) Cree su propia clase para la nueva asignación (/ external / oauth / token) y extienda el tokenendpoint.

4) Cambie el valor del atributo del patrón del elemento http & intercept-url a "/ external / oauth / token"


Solo luché con esto por unos días, pero haz que funcione ahora en el último Spring Oauth2 1.0.5.RELEASE. No estoy 100% seguro de que mi solución sea la más elegante (en particular, el Paso 4), pero funciona y puedo avanzar.

En mi caso, quería eliminar el prefijo /oauth de las direcciones URL para terminar con /token y /authorize . La solución para mí fue principalmente la configuración xml, con dos hacks para anular los mapeos de solicitud de punto final.

1 - En el contexto de la aplicación xml, agregue los atributos de author authorization-endpoint-url y token-endpoint-url a su elemento <oauth:authorization-server> .

Mía:

<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token">

2 - En el contexto de la aplicación xml, ajuste los puntos finales de seguridad en consecuencia. Debería haber dos, que administren la seguridad respectivamente en el token y en las URL de autenticación. Necesidad de actualizar el patrón prop en las etiquetas <http> y <intercept-url> .

Mía:

<http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security"> <intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" /> ... <http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security"> <intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" />

3 - (Si eligió emplear el filtro clientCreds opcional). En el contexto de la aplicación xml, ya debería haber conectado en el bean clientCredentialsTokenEndpointFilter como un <custom-filter> within your element. So, within the filter''s bean, add a element. So, within the filter''s bean, add a propiedad filterProcessesUrl`.

Mía:

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

4 - El último paso es anular las urls de asignación de solicitud de los controladores de punto final internos reales. Spring oauth2 lib viene con dos clases: AuthorizationEndpoint y TokenEndpoint . Cada uno utiliza anotaciones de tipo @RequestMapping para enlazar la url (como lo hacemos todos para los controladores de aplicaciones de nuestros proyectos). Para mí, fue un esfuerzo alucinante intentar anular el valor de las asignaciones de solicitud de cualquier otra manera que no sea (lamentablemente) volver a crear el paquete de clase spring en mi carpeta src, copiar las clases AuthorizationEndpoint y TokenEndpoint de forma literal en dicha carpeta. y edite los valores de anotación en línea @RequestMapping .

De todos modos, eso hace el truco. Me encantaría saber de una manera más elegante de anular los valores de mapeo de solicitud de controlador de punto final.

Gracias.

Final, contexto de aplicación de trabajo:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd " xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <!-- Declare OAuth2 services white-list. (This is the top of the config.) --> <oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token"> <oauth:authorization-code /> <oauth:implicit /> <oauth:refresh-token /> <oauth:client-credentials /> <!-- <oauth:password /> --> </oauth:authorization-server> <bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler"> <!-- This bean bridges client auth service and user tokens... kind of an out of place requirement. --> <property name="tokenServices" ref="tokenServices" /> </bean> <!-- This starts the far back-end config for client token management. --> <sec:authentication-manager id="clientAuthenticationManager"> <sec:authentication-provider user-service-ref="clientDetailsUserService" /> </sec:authentication-manager> <bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> <constructor-arg ref="clientDetailsService" /> </bean> <bean id="clientDetailsService" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOauth2ClientDetailsService"> <!-- This bean is what wires OAuth2 into the persistence stack for client details stored in the oauth_client table. --> </bean> <!-- OAuth is layered on to spring security which is centered around users which requires a user auth manager. --> <authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security"> <authentication-provider ref="daoAuthenticationProvider" /> </authentication-manager> <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="userDetailsService" /> </bean> <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"> <property name="tokenStore" ref="tokenStore" /> <property name="supportRefreshToken" value="true" /> <property name="clientDetailsService" ref="clientDetailsService" /> </bean> <bean id="tokenStore" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOAuth2TokenStore"> <!-- This bean is what wires OAuth2 tokens into my company''s application stack. --> <constructor-arg ref="dataSource" /> </bean> <!-- **************************************************************************************** --> <!-- Finally, sew OAuth into spring security with some http tags... --> <!-- **************************************************************************************** --> <!-- The OAuth2 endpoint for direct token requests (i.e. for client_credentials flow). --> <http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security"> <intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" /> <anonymous enabled="false" /> <http-basic entry-point-ref="clientAuthenticationEntryPoint" /> <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> <access-denied-handler ref="oauthAccessDeniedHandler" /> </http> <bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> <property name="authenticationManager" ref="clientAuthenticationManager" /> <property name="filterProcessesUrl" value="/token" /> </bean> <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="myrealm" /> </bean> <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /> <!-- The OAuth2 endpoint for user-approved authorization (i.e. for "authorization" flow involving user login/approve). --> <http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security"> <intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" /> <form-login authentication-failure-url="/login.jsp?authentication_error=true" default-target-url="http://www.mycompany.com/" login-page="/login.jsp" login-processing-url="/login.do" /> <http-basic /> <anonymous /> </http> </beans>