I am using jasig cas4.0 server. I have implemented the Facebook oAuth2.0 support in my cas server and it works correctly. Now, I want to add Google oauth support (Google2Client) in the same CAS-server.
1) I created a new Project in console.developers.google.com, created a new client id under the OAuth with redirect uri to https://rajan.com:1443/cas/login (which actually points to localhost)
2) I added this to my applicationcontext.xml
<bean id="google1" class="org.pac4j.oauth.client.Google2Client">
<property name="key" value="<<CLIENT_ID>>" />
<property name="secret" value="<CLIENT_SECRET" />
<property name="scope" value="email" />
<property name="fields" value="id,name,first_name,middle_name,last_name,gender,email" />
</bean>
I also registered this bean in the clients
<bean id="clients" class="org.pac4j.core.client.Clients">
<property name="callbackUrl" value="https://rajan.com:1443/cas/login" />
<property name="clients">
<list>
<ref bean="facebook1" />
<ref bean="google1" />
</list>
</property>
</bean>
3) And finally, I added this in casLoginView.jsp
Authenticate with Facebook <br />
Authenticate with Google <br />
But, When I open the cas login view in the browser, the href for Google contains "https://rajan.com:1443/cas/login?service=https%3A%2F%2Frajan.com%3A2443%2FCasClientSimple%2F" instead of Google Oauth url. The facebook link works fine.
Could someone help me what I am missing here.
Thank you.
I checked the Google2OauthClient. There were no fields property.
So, just deleting the fields property in the above bean worked.
I also changed the field email with EMAIL_AND_PROFILE
Related
I'm getting the below error when using BCryptPasswordEncoder in CAS 4.2 (Central Authentication Service).:
java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder] to required type [org.jasig.cas.authentication.handler.PasswordEncoder] for property 'passwordEncoder': no matching editors or conversion strategy found
I've added all the dependencies in Maven. I also checked over CAS documents, but there is no proper information about how to configure BCryptPasswordEncoder with CAS.
deployerconfigcontext.xml (Maven for compilation):
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:passwordEncoder-ref="passwordEncoder"
p:sql="select PASSWORD from SD_AD_DAT_LOGIN where ACCESS_NAME=?" />
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
I've connected CAS with the Oracle database, and it validated the plain text password correctly. Now I want to use bcrypt password encoding, and store the encode password in the database so that CAS should validate the encode password.
Help me understand the usage of BCryptPasswordEncoder with CAS.
After some more analysis i got to know that CAS 4.2.7 doesn't support Bcrypt encoding so to use this we need to write new custom class (BCryptSearchModeSearchDatabaseAuthenticationHandler) to handle bcrypt encoding.
deployerconfig.xml :
<bean id="primaryAuthenticationHandler"
class="io.wicket.cas.BCryptSearchModeSearchDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:tableUsers="SD_AD_DAT_LOGIN"
p:fieldUser="ACCESS_NAME"
p:fieldPassword="PASSWORD"
p:passwordEncoder-ref="passwordEncoder"/>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#172.16.0.72:1521:xe" />
<property name="username" value="PROD17102018" />
<property name="password" value="PROD17102018" />
</bean>
My web application has a bunch "normal" resources (html pages etc) and also some REST resources which are called from JavaScript by the previously mentioned html pages.
If there is a session timeout the user gets redirected to the login form. That's great for the "normal" resources, but not for the REST resources. I'll just need a 403 response there so that the JavaScript can take over and ask the user to reauthenticate.
There are countless examples on the web how to configure each of those, but I could not find an example on how to combine the methods. All my API URLs start with "/api/", so I'll need the 403 for all those URLs and the redirect for all the remaining URLs. How do I set this up?
It took me a little bit of Spring source code study to get this to work. You can set up an authentication entry point as follows:
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<!-- this is the configuration for /api/ URLs -->
<constructor-arg>
<map>
<entry>
<key>
<bean class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
<constructor-arg value="^/api/.*" /><!-- match URLs starting with "/api/" -->
<constructor-arg><null /></constructor-arg><!-- no matter what the HTTP method is -->
</bean>
</key>
<!-- if the key above has matched, send 403 response -->
<bean class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
</entry>
</map>
</constructor-arg>
<!-- and in the default case just redirect to login form -->
<property name="defaultEntryPoint">
<bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/spring_security_login" />
</bean>
</property>
</bean>
This can then be used in the Sping Security configuration:
<http ... entry-point-ref="authenticationEntryPoint">
I think that you should just have two different <http pattern="{...}" ...> entities, because, ok, you solved the problem with the redirect, but what about csrf protection? And other problems that I can't think of of the top of my head.
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
I wonder how/where can I manage Authentication at SecurityContext in pre-authentation Scenario.
I am using spring security 2.x to implement pre-authentation Scenario in my project. now, it patially work.
After user login by pre-authentation process, they can be authrozied with relevant roles, and are able to acecess resources which defined in security:filter.
e.g.
<security:filter-invocation-definition-source lowercase-comparisons="true" path-type="ant">
<security:intercept-url pattern="/resource/**" access="ROLE_ADMIN" />
In a some controller, I want to check principal in security content.
public abstract class AbstractUserAuthenticationController extends AbstractController
{
protected boolean isAuthenticated(String userName)
{
Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // where issue come up
But SecurityContextHolder.getContext().getAuthentication() always return null.
In addition, I also can not use secuiry tag in jsp to check if user has relative roles
<security:authorize ifNotGranted="ROLE_ADMIN">
no role found
</security:authorize>
Below shows the "filterChainProxy" I am using.
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/*subscri*=httpSessionContextIntegrationFilter,logoutFilter,j2eePreAuthenticatedProcessingFilter,securityContextHolderAwareRequestFilter,subscribeExceptionTranslationFilter,filterInvocationInterceptor
/**=httpSessionContextIntegrationFilter,logoutFilter,j2eePreAuthenticatedProcessingFilter,logoutFilter,rememberMeProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
</value>
</property>
</bean>
<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService" />
</bean>
<bean id="preAuthenticatedUserDetailsService" class="demo.project.security.auth.RsaAuthenticationUserDetailsService" >
<property name="userService" ref="userService" />
</bean>
<bean id="j2eePreAuthFilter" class="demo.project.security.filter.AutoLoginFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="userService" ref="userService" />
</bean>
I think I need to set Authentication to SecurityContext in somewhere, But I do not know where/where.
What I am missing? Can anyone provide me some clues?
Thanks!
Ian
You should use SecurityContextHolder.setContext method to store your SecurityContext prior to getting it back.
The simplest way for doing this is just SecurityContextHolder.setContext(new SecurityContextImpl()).
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>