Spring OAuth2 XML configuration for Client and Resource Server [closed] - spring-security

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Can any one help me with a very basic configuration in XML to act my spring application as OAuth2/OIDC Resource serer and as well as cilent.
What I have?
A Spring Web MVC application with Spring Secuirity LDAP authentication.
What I want to achieve?
If user tries to access any resource(e.g. index.html) in my application, he should be asked for his credentials(can be popup or can be a redirect to login page).
Application should connect with a third party Authorization server and get the OAuth2 access token and refresh token.
Once the access token is received, application should create the session and serve the required resource asked in first step.
When user clicks on logout or the session is expired, flow starts from first step.
What I have tried so far?
I have tried this with Spring boot and OIDC. But I am looking for some good reference to achieve the above with XML configuration. Please note that I can not use Spring Boot or any java configuration.
Any ideas or suggestions on how to start all this?
Thanks.

First, I must say that you can find good examples in Spring's oAuth Samples section.
Anyhow, I have created an oAuth-sample-project (GitHub) when I played with it a while back, so here are the interesting parts. Take into account that you have to learn a bit from the docs, and drill in the code... but I think it is good for a starting point.
The client XML:
<sec:http authentication-manager-ref="authenticationManager">
<sec:intercept-url pattern="/secure/**" access="ROLE_USER" />
<sec:anonymous/>
<!-- sec:form-login/-->
<sec:form-login
login-page="/login/login.htm"
authentication-failure-url="/login/login.htm?login_error=1" />
<sec:custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider user-service-ref="userDetailsService"/>
</sec:authentication-manager>
<sec:user-service id="userDetailsService">
<sec:user name="admin" password="admin" authorities="ROLE_USER,ROLE_ADMIN" />
</sec:user-service>
<!--apply the oauth client context-->
<oauth:client id="oauth2ClientFilter" />
<oauth:resource id="butkecResource"
type="authorization_code"
client-id="${oauth2.client.id}"
client-secret="${oauth2.client.secret}"
access-token-uri="${oauth2.client.accessTokenUri}"
user-authorization-uri="${oauth2.client.userAuthorizationUri}"
scope="read"/>
<!--define an oauth2 resource for facebook. according to the facebook docs, the 'client-id' is the App ID, and the 'client-secret'
is the App Secret -->
<oauth:resource id="facebook"
type="authorization_code"
client-id="233668646673605"
client-secret="33b17e044ee6a4fa383f46ec6e28ea1d"
authentication-scheme="query"
access-token-uri="https://graph.facebook.com/oauth/access_token"
user-authorization-uri="https://www.facebook.com/dialog/oauth"
token-name="oauth_token"
client-authentication-scheme="form" />
full snippet is here.
the resource server XML:
<security:http pattern="/index.html" security="none"/>
<security:http pattern="/browse" security="none"/>
<!-- security:http pattern="/welcome" security="none"/-->
<security:http pattern="/js/**" security="none"/>
<security:http entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager">
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
<security:anonymous />
</security:http>
...
...
<oauth:resource-server id="resourceServerFilter"
token-services-ref="tokenServices" />
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices" >
<property name="tokenStore" ref="tokenStore" />
</bean>
<bean id="tokenStore" class="com.ohadr.oauth.resource_server.token.MyTokenStore" />
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="butkec" />
</bean>
file can be found here.
I think here is not a good place to explain every bit and byte, but again - in Spring docs you can find great explanations (I managed to learn all from there...)

Related

spring securit3.x y integration with wicket 6.7.0

I am new to wicket and SpringSecurity. I configured the spring security as follows.
<http create-session="never" auto-config="true">
<remember-me />
<http-basic />
<intercept-url pattern="/**" requires-channel="https" />
<!-- <form-login login-page="/admin"/> <logout invalidate-session="true"
logout-url="/j_spring_security_logout" logout-success-url="/admin" delete-cookies="JSESSIONID"/> -->
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</session-management>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService"></authentication-provider>
</authentication-manager>
<global-method-security secured-annotations="enabled" />
I have extended the AuthenticatedWebSession doing the authentication in my extended class.
My Questions :
How can I configure for form based Authentication.
How can I configure for Session Management.
How can I configure for Single Sign in per user (Here if the user try to login with same user I want invalidate the session of the previous logged in user. )
Need reference manual on Spring Security Integration with Wicket.
Please also let me know if I am missing anything.
you can have a look at the following working example on Wicket / Spring-Security integration on github: https://github.com/thombergs/wicket-spring-security-example.
Your questions are a little vague for a helpful answer, so I'd suggest yoiu have a look at the example on github and ask again if you have any problems.
Regards,
Tom

Customizing authentication exceptions spring oauth

I'm using jersey as a RESTFul webserver. (jersey-server 1.8) with spring (3.2.0.RELEASE) and hibernate.
My endpoints are protected using spring-security (3.1.3.RELEASE) with 2 legged oAuth 1.0a (spring-security-oauth 1.0.0.M4 )
Everything works as expected and the securing works.
Inside my ConsumerDetailsServiceImpl (implements ConsumerDetailsService, UserDetailsService, AuthenticationProvider) i throw different exceptions (all are of form OAuthException now, but i want to add my own custom exceptions)
However no matter what i tried i cannot get to customize the different authentication and access denied exceptions the way i want, i always get the default 401 page
My API is agreed to always return a json responseobject so i need to catch these exceptions and show 401 pages with json inside it
My securty.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth.xsd">
<!-- Authentication beans -->
<bean name="consumerDetailsService" class="com.securitytest.core.services.impl.ConsumerDetailsServiceImpl" />
<bean name="oauthProcessingFilterEntryPoint" class="org.springframework.security.oauth.provider.OAuthProcessingFilterEntryPoint" />
<bean id="oAuthAuthenticationHandler" class="com.securitytest.core.security.CustomOAuthAuthenticationHandler" />
<security:http auto-config="true" use-expressions="true" entry-point-ref="oauthProcessingFilterEntryPoint" >
<security:intercept-url pattern="/rest/secured/**" access="isAuthenticated()" />
<security:intercept-url pattern="/rest/unsecured/**" access="permitAll" />
<security:intercept-url pattern="/rest/**" access="isAuthenticated()" />
<security:form-login login-page='/login' default-target-url="/home" authentication-failure-handler-ref="authenticationFailureHandler"/>
<security:access-denied-handler ref="accessDeniedHandler" />
</security:http>
<bean id="accessDeniedHandler" class="com.securitytest.core.security.CustomoauthAccessDeniedHandler" />
<!-- this was just a test, it didn't work obviously -->
<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.security.authentication.BadCredentialsException">/login/badCredentials</prop>
<prop key="org.springframework.security.authentication.CredentialsExpiredException">/login/credentialsExpired</prop>
<prop key="org.springframework.security.authentication.LockedException">/login/accountLocked</prop>
<prop key="org.springframework.security.authentication.DisabledException">/login/accountDisabled</prop>
</props>
</property>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="consumerDetailsService" />
</security:authentication-manager>
<bean id="nonceServices" class="org.springframework.security.oauth.provider.nonce.InMemoryNonceServices" />
<oauth:provider
auth-handler-ref="oAuthAuthenticationHandler"
consumer-details-service-ref="consumerDetailsService"
nonce-services-ref="nonceServices"
token-services-ref="tokenServices"
require10a="true"
/>
<oauth:token-services id="tokenServices" />
Stuff i tried
Change the exceptionTranslationFilter -> is not allowed by the docs
Add a custom access-denied-handler and a authentication-failure-handler-ref
<security:http auto-config="true" use-expressions="true" entry-point-ref="oauthProcessingFilterEntryPoint" >
<security:intercept-url pattern="/rest/secured/**" access="isAuthenticated()" />
<security:intercept-url pattern="/rest/unsecured/**" access="permitAll" />
<security:intercept-url pattern="/rest/**" access="isAuthenticated()" />
<security:form-login login-page='/login' default-target-url="/home" authentication-failure-handler-ref="authenticationFailureHandler"/>
<security:access-denied-handler ref="accessDeniedHandler" />
</security:http>
-> this gets blatantly ignored by spring-security/oauth
Add a custom filter after the EXCEPTION_TRANSLATION_FILTER
<security:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="myFilter" />
MyFilter just implements "javax.servlet.Filter".
-> It goes into the doFilter but i have no idea what do with it (i can't see which exception is thrown, if any).
Any help is appreciated!!
I am quite late answering this question and you might have resolved or moved to some other alternative. However I recently dived into the Oauth and faced similar problem and managed to resolve it. Sharing it as reference for others.
I have used Oauth's MediaTypeAwareAccessDeniedHandler and MediaTypeAwareAuthenticationEntryPoint for error handling. As per documentation, it defaults to 401 error page. However, from source code, error response content type is dependent upon request Accept-Type. But requesting clients to always sent Accept-Type as application/json is like asking fox to safeguard hen.
Good news is that response type support setter injection. So simple solution was to override defaults and inject response property to always sent JSON response irrespective of Accept-Type
<bean id="accessDeniedHandler" class="org.springframework.security.oauth2.provider.error.MediaTypeAwareAccessDeniedHandle"/>
<property name="responses">
<map>
<entry key="*/*" value="{error:"%s"}"></entry>
</map>
</property>
</bean>

Unable to Configure Spring Security With X.509 Certificate and Anonymous User

I am attempting to authenticate via X.509 smart card to my application. For the moment, my application doesn't have any users defined, so I'm trying to use anonymous authentication. I'll switch it to hasRole() once I create users.
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="myUserService" />
</security:authentication-manager>
<!-- TODO: Enable this once I am ready to start annotating the service interfaces -->
<security:global-method-security pre-post-annotations="enabled" />
<security:http use-expressions="true" authentication-manager-ref="authenticationManager" access-denied-page="/index2.xhtml" >
<security:anonymous enabled="true" />
<security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="myUserService" />
<security:intercept-url pattern="/**" access="isAnonymous()" requires-channel="https" />
<!-- TODO: configure invalid-session-url, delete sessionid -->
<security:session-management>
<security:concurrency-control max-sessions="2" error-if-maximum-exceeded="true"/>
</security:session-management>
</security:http>
<bean id="roleVoter"
class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_USER > ROLE_AUTHENTICATED
ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED
ROLE_UNAUTHENTICATED > ROLE_ANONYMOUS
</value>
</property>
</bean>
It seems to be caught in the infinite loop issue, which I thought I was avoiding using isAnonymous().
I'm probably making a dumb error, so if someone can point out said stupidity, I'd be grateful.
The issue was a problem with configuring FacesServlet in web.xml. The FacesServlet was mapped to one path, which seemed to be incompatible with the intercept-url defined for Spring Security.
We've since jettisoned JSF (and good riddance).

How to use J2eePreAuthenticatedProcessingFilter and a custom authentication provider?

I want my Spring application to try two pre-authentication methods (Siteminder and Java EE container authentication).
If either of these filters locates a username - I want to check that username against my database of users and assign roles based on what I see in the database. (I have an implementation of AuthenticationUserDetailsService, which does that for me.)
If not - show a login page to the user. Check the credentials they enter in the form against my database of users.
The Siteminder integration is working. The login form is working too. My problem is with the Java EE pre-authentication. It never kicks in.
My applicationContext-security.xml:
<!-- HTTP security configurations -->
<sec:http auto-config="true" use-expressions="true">
<sec:form-login login-processing-url="/resources/j_spring_security_check" always-use-default-target="true" default-target-url="/" login-page="/login"
authentication-failure-url="/login?login_error=t" />
<sec:logout logout-url="/resources/j_spring_security_logout" />
<sec:access-denied-handler error-page="/accessDenied" />
<sec:remember-me user-service-ref="customUserDetailsService" token-validity-seconds="86400" key="OptiVLM-VaultBalance" />
<sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter"/>
<sec:custom-filter after="PRE_AUTH_FILTER" ref="jeePreAuthenticatedFilter"/>
<!-- various intercept-url elements here, skipped for brevity -->
</sec:http>
<!-- Authentication Manager -->
<sec:authentication-manager alias="authenticationManager">
<!-- J2EE container pre-authentication or Siteminder -->
<sec:authentication-provider ref="customPreAuthenticatedAuthenticationProvider" />
<!-- Default provider -->
<sec:authentication-provider user-service-ref="customUserDetailsService" />
</sec:authentication-manager>
<!-- Siteminder pre-authentication -->
<bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="exceptionIfHeaderMissing" value="false" />
</bean>
<!-- J2EE pre-authentication -->
<bean id="jeePreAuthenticatedFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<!-- Custom pre-authentication provider -->
<bean id="customPreAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="customAuthenticationUserDetailsService" />
</bean>
I have Java 2 security enabled in Websphere, and I am logged in as 'admin5'. (I have a user with this username in my user database.) But when I access the application, there is never a call to the 'customAuthenticationUserDetailsService' bean to verify the username. I know this, because 'customAuthenticationUserDetailsService' does extensive logging which clearly shows what it is doing. When I am using the Siteminder pre-authentication - the 'customAuthenticationUserDetailsService' works just fine, I get some trace output in the log. But not for the J2EE authentication...
My guess is that one of these things is happening:
a) Java EE pre-authentication filter is not locating the username, so it never calls the authentication manager
b) Java EE pre-authentication filter works fine, but my custom authentication provider is never called by the authentication manager for some reason
By the way, the default authentication provider, which uses 'customUserDetailsService' does not kick in either. Again, I can tell that because there is no output from 'customUserDetailsService' in the log.
Can you advise on what could be the problem here? If not a solution, then a suggestion on how to approach this would be greatly appreciated.
OK, I figured this out. The problem is that even though I had J2EE security setup in Websphere and was authenticated, my web.xml contained no security constraints. Because of this, Websphere was not supplying the principal for my requests. This is apparently an intentional feature. If you are not accessing a protected URL, you should not need the pre-authentication information.
To overcome this, I added a security constraint to my web.xml, which allowed ALL users to access the resources. Effectively, the resources were not secured, but still - there was a constraint now.
This is it:
<security-constraint>
<web-resource-collection>
<web-resource-name>All areas</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
This tricks the Websphere into filling in the user principal information in the request.
Thank you #Ralph for his comments on this this question: request.getUserPrincipal() got null

Creating a custom authentication with Acegi/Spring Security

I'm having trouble discovering exactly what I need to implement in order to use a custom authentication method with my web application using Spring Security. I have a Grails application with the Spring Security plugin that currently uses the standard user/password authentication with a browser form. This is working correctly.
I need to implement a mechanism alongside of this that implements a type of MAC authentication. If the HTTP request contains several parameters (e.g. a user identifier, timestamp, signature, etc.) I need to take those parameters, perform some hashing and signature/timestamp comparisons, and then authenticate the user.
I'm not 100% sure where to start with this. What Spring Security classes do I need to extend/implement? I have read the Reference Documentation and have an okay understanding of the concepts, but am not really sure if I need a Filter or Provider or Manager, or where/how exactly to create Authentication objects. I've messed around trying to extend AbstractProcessingFilter and/or implement AuthenticationProvider, but I just get caught up understanding how I make them all play nicely.
Implement a custom AuthenticationProvider which gets all your authentication information from the Authentication: getCredentials(), getDetails(), and getPrincipal().
Tie it into your Spring Security authentication mechanism using the following configuration snippet:
<bean id="myAuthenticationProvider" class="com.example.MyAuthenticationProvider">
<security:custom-authentication-provider />
</bean>
This step is optional, if you can find a suitable one from standard implementations. If not, implement a class extending the Authentication interface on which you can put your authentication parameters:
(e.g. a user identifier, timestamp, signature, etc.)
Extend a custom SpringSecurityFilter which ties the above two classes together. For example, the Filter might get the AuthenticationManager and call authenticate() using your implementation of Authentication as input.
You can extend AbstractAuthenticationProcessingFilter as a start.
You can reference UsernamePasswordAuthenticationFilter which extends AbstractAuthenticationProcessingFilter. UsernamePasswordAuthenticationFilter implements the standard Username/Password Authentication.
Configure your Spring Security to add or replace the standard AUTHENTICATION_PROCESSING_FILTER. For Spring Security Filter orders, see http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#filter-stack
Here is a configuration snippet for how to replace it with your implementation:
<beans:bean id="myFilter" class="com.example.MyAuthenticationFilter">
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</beans:bean>
I have recently put up a sample application that does custom authentication with Spring Security 3.
The source code is here.
More details are in this blog post.
Here is an example of securityContext.xml configuration file using custom autenticationFilter (extending AUTHENTICATION_PROCESSING_FILTER) and authenticationProvider. The user authentication data is provided by jdbc connection. Configuration is for Spring Security 2.0.x
<?xml version="1.0" encoding="UTF-8"?>
<sec:global-method-security />
<sec:http auto-config="false" realm="CUSTOM" create-session="always" servlet-api-provision="true"
entry-point-ref="authenticationProcessingFilterEntryPoint" access-denied-page="/notauthorized.xhtml"
session-fixation-protection="migrateSession">
<sec:port-mappings>
<sec:port-mapping http="80" https="443" />
</sec:port-mappings>
<sec:anonymous granted-authority="ROLE_ANONYMOUS" username="Anonymous" />
<sec:intercept-url pattern="/**" access="ROLE_ANONYMOUS, ROLE_USER" />
<sec:logout logout-url="/logoff" logout-success-url="/home.xhtml" invalidate-session="false" />
</sec:http>
<bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.xhtml" />
<property name="forceHttps" value="false" />
</bean>
<bean id="authenticationProcessingFilter" class="mypackage.CustomAuthenticationProcessingFilter">
<sec:custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
<property name="defaultTargetUrl" value="/" />
<property name="filterProcessesUrl" value="/logon" />
<property name="authenticationFailureUrl" value="/loginError.xhtml" />
<property name="alwaysUseDefaultTargetUrl" value="false" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<jee:jndi-lookup id="securityDataSource" jndi-name="jdbc/DB_DS" />
<bean id="myUserDetailsService" class="mypackage.CustomJdbcDaoImpl">
<property name="dataSource" ref="securityDataSource" />
<property name="rolePrefix" value="ROLE_" />
</bean>
<bean id="apcAuthenticationProvider" class="mypackage.CustomDaoAuthenticationProvider">
<property name="userDetailsService" ref="myUserDetailsService" />
<sec:custom-authentication-provider />
</bean>
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<ref local="apcAuthenticationProvider" />
</list>
</property>
</bean>
</beans>

Resources