I am working on Mule CE and need to implement token based security (preferably) using Oauth2. I have configured the authorization-server and I do see the default mappings in the log file, however when I send message on "/oauth/token" nothing happens.
Similar config of OAuth2 works fine with Spring/Tomcat when deployed as standalone Spring web service application on Tomcat.
Here is my Mule config:
<mule xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml"
xmlns:https="http://www.mulesoft.org/schema/mule/https" xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.0"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:ss="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:pattern="http://www.mulesoft.org/schema/mule/pattern" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.mulesoft.org/schema/mule/xml
http://www.mulesoft.org/schema/mule/xml/3.3/mule-xml.xsd
http://www.mulesoft.org/schema/mule/http
http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core
http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/https
http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.mulesoft.org/schema/mule/jersey
http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.mulesoft.org/schema/mule/spring-security
http://www.mulesoft.org/schema/mule/spring-security/3.3/mule-spring-security.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.mulesoft.org/schema/mule/pattern
http://www.mulesoft.org/schema/mule/pattern/3.3/mule-pattern.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd ">
<mule-ss:security-manager>
<mule-ss:delegate-security-provider
name="memory-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider ref="myAuthenticationProvider" />
</ss:authentication-manager>
<oauth:client-details-service id="clientDetailsService">
<oauth:client client-id="admin"
authorized-grant-types="password,authorization_code,refresh_token,implicit,client_credentials"
authorities="ROLE_USER, ROLE_TRUSTED_CLIENT" scope="read,write,trust"
access-token-validity="60" />
</oauth:client-details-service>
<oauth:authorization-server
client-details-service-ref="clientDetailsService" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
</spring:beans>
<spring:beans>
<mvc:annotation-driven />
<spring:bean id="myAuthenticationProvider"
class="com.sachin.tech.security.MyUserAuthenticationProvider" />
<spring:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<spring:property name="realmName" value="myCustomerAppRealm" />
</spring:bean>
<spring:bean id="oauth2AccessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl" />
<spring:bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<spring:property name="authenticationManager" ref="authenticationManager" />
</spring:bean>
<spring:bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<spring:bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<spring:property name="tokenStore" ref="tokenStore" />
<spring:property name="supportRefreshToken" value="true" />
<spring:property name="accessTokenValiditySeconds"
value="60" />
</spring:bean>
</spring:beans>
<flow name="wsauthentication_2" doc:name="wsauthentication_2">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="8098" doc:name="MyHTTPInbound2_2"
doc:description="wsauthentication_2 Desc">
</http:inbound-endpoint>
<echo-component doc:name="Echo" />
</flow>
</mule>
The mapping seems to be fine in logs:
13:48:01,789 DEBUG FrameworkEndpointHandlerMapping:125 - Looking for request mappings in application context: org.mule.config.spring.MuleApplicationContext#7fe3a7ec: startup date [Tue Apr 23 13:47:56 IST 2013]; root of context hierarchy
13:48:01,836 INFO FrameworkEndpointHandlerMapping:197 - Mapped "{[/oauth/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.handleError(javax.servlet.http.HttpServletRequest)
13:48:01,836 INFO FrameworkEndpointHandlerMapping:197 - Mapped "{[/oauth/confirm_access],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>) throws java.lang.Exception
13:48:01,851 INFO FrameworkEndpointHandlerMapping:197 - Mapped "{[/oauth/authorize],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.lang.String,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
13:48:01,851 INFO FrameworkEndpointHandlerMapping:197 - Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
13:48:01,851 INFO FrameworkEndpointHandlerMapping:197 - Mapped "{[/oauth/token],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.lang.String,java.util.Map<java.lang.String, java.lang.String>)
Please help.
I don't think Sprint OAuth can actually work outside of a Java web container.
For Mule EE, you can use the OAuth2 provider from the Enterprise Security package.
For Mule CE, you could try to run an embedded Jetty container and use Mule's Servlet endpoints behind it. That should provide an environment in which Spring OAuth could work. See the Bookstore example, provided with the Mule distribution, for inspiration.
Related
I have 2 api to request:
API get token
API request to work something (use OAuth2)
Below is code to call get token:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/default" name="PostToken" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET">
<inSequence>
<payloadFactory description="Setting payload for GetAccessToken API" media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<grant_type>$1</grant_type>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg value="client_credentials"/>
</args>
</payloadFactory>
<!-- Below configurations are required to send data as application/x-www-form-urlencoded -->
<header name="Content-Type" scope="transport" value="application/x-www-form-urlencoded"/>
<property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<header name="Authorization" scope="transport" value="Basic xxxxxxxx"/>
<property name="POST_TO_URI" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint>
<http method="post" uri-template="https://sample.com/token">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
How next step I can get token from response to apply the 2nd API with Bearer token?
Many thanks!
You can refer to the following blog regarding the Using OAuth2 Protected Back-ends With API Manager., This blog is regarding handling that in the WSO2 API Manager. But this is applicable in the EI as well.
[1] https://medium.com/#menakajayawardena/wso2-how-to-using-oauth2-protected-back-ends-with-api-manager-5d7e234c61c
I have a situation:
Step 1: Obtained access token (grant_type=password) (A1) and also a refresh token.(RT1)
Step 2: Accessed resource (R) using the token (A1) - Success
Step 3:Revoked user access role for Resource R.
Step 4: Obtained access token (grant_type=password) (A2) and also a refresh token.(RT2)
Step 5: Accessed resource (R) using the token (A2) - Failed
till here all fine.now comes the unexpected part.
Step 6: Obtained new access token (grant_type=refresh_token) using RT2. Unexpectedly using this access token i was able to access resource R.
During this whole flow none of the token was expired one.
I see two issues here:- User roles aren't getting updated for refresh token on grant_type=password and for grant_type=refresh_token. Although access token has changed (Step 4) but refresh token remains same RT1 == RT2. hence any further usage of RT gives access token with previous roles.
How do i tell spring (oauth2) to update user roles (for the newly created token's) while obtaining the access token using refresh token and also while updating RT with new roles (step4), to resolve this discrepancy.
Below is the Authorization server configuration:
<?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.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<bean class="com.dummy.mc.security.service.UserDetailsServiceImpl">
<property name="userRepository" ref="userRepository" />
<property name="grantedAuthorityRepository" ref="grantedAuthorityRepository" />
</bean>
</property>
<property name="passwordEncoder">
<bean class="com.dummy.mc.security.password.McpmPasswordEncoder">
<property name="encodeHashAsBase64" value="true" />
</bean>
</property>
<property name="saltSource">
<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="salt" />
</bean>
</property>
</bean>
<!--https://stackoverflow.com/questions/49761597/spring-oauth2-clientid-passed-in-as-username-for-password-grant-type-->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="dataSource" />
</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" />
<property name="reuseRefreshToken" value="false"/>
</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="clientDetailAuthenticationManager" />
</bean>
<!-- Authentication manager for client (not resource-owner) authentication required to
protect the token endpoint URL -->
<security:authentication-manager id="clientDetailAuthenticationManager">
<security:authentication-provider user-service-ref="clientDetailsUserService"/>
</security:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetailsService"/>
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<security:http pattern="/oauth/token" create-session="stateless" use-expressions="true" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/oauth/token" access="isAuthenticated()" />
<security:anonymous enabled="false" />
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>
<authorization-server client-details-service-ref="clientDetailsService"
xmlns="http://www.springframework.org/schema/security/oauth2" token-services-ref="tokenServices" >
<authorization-code />
<implicit />
<refresh-token />
<client-credentials />
<password authentication-manager-ref="authenticationManager" />
</authorization-server>
<!-- <oauth:resource-server id="resourceFilter" token-services-ref="tokenServices" authentication-manager-ref="authenticationManager" />
-->
<security:authentication-manager id="authenticationManager">
<security:authentication-provider ref="daoAuthenticationProvider">
</security:authentication-provider>
</security:authentication-manager>
<oauth:client-details-service id="clientDetailsService">
<oauth:client client-id="core-api" secret="secret"
authorized-grant-types="password,client_credentials,refresh_token" scope="read"
resource-ids="api-core" access-token-validity="36000"
authorities="ROLE_CLIENT,ROLE_TRUSTED_CLIENT" />
</oauth:client-details-service>
</beans>
Resource Server Configuration:
<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<security:global-method-security pre-post-annotations="enabled"/>
<!-- TODO: make an access denied view that tells me something useful -->
<security:http use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint">
<security:intercept-url pattern="/**" access="isFullyAuthenticated() and hasRole('api.core')" />
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
<security:anonymous />
</security:http>
<!-- It's just a "feature" of the Spring Security that an authentication manager is mandatory.
so install an empty one because it isn't used at run time -->
<security:authentication-manager/>
<oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices" resource-id="api-core"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices" >
<property name="tokenStore" ref="tokenStore" />
</bean>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="dataSource" />
</bean>
<bean id="oauthAuthenticationEntryPoint" 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" />
Authorities are loaded when access token its required.
Using jdbc store, authorities are saved to OAUTH_ACCESS_TOKEN table, AUTHENTICATION column.
When refresh token its required, authorities are loaded from database.
If authorities changed after access token was required, you will have to implement custom token store.
Take a look to org.springframework.security.oauth2.provider.token.store.JdbcTokenStore, and extend from it.
I'm trying to use spring security 4 with ldap. it works fine for the LDAP who as the basic authentication system. If I try to connect to a system that uses GSS no longer works. I think it is normal and should be specified using GSS somewhere. But where?
Below is the xml file security
<?xml version="1.0" encoding="UTF-8"?>
<beans:bean xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-4.1.xsd
">
<!-- This is where we configure Spring-Security -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="isAuthenticated()" />
<intercept-url pattern="/user**" access="hasAuthority('1')" />
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/planning"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password"
authentication-success-handler-ref="customLdapAuthenticationSuccessHandler"
/>
<logout logout-url="/logout" logout-success-url="/login?logout" />
</http>
<ldap-server url="ldap://192.168.2.100/DC=ciro,DC=local,DC=it?one?(objectClass=*)" manager-dn="cn=Administrator,dc=web-gate,dc=local,dc=it" manager-password="PLAIN PWD" />
<authentication-manager>
<ldap-authentication-provider
group-search-base="ou=groups">
</ldap-authentication-provider>
</authentication-manager>
</beans:bean>
Spring LDAP has never supported the GSSAPI SASL mechanism. Luckily, you can use my library to do that with Spring LDAP. The configuration is straight forward.
I have two web roles within a cloud service, one to expose outside and one for internal use. The external web role has an MVC web application which will have to connect to the internal web role which will have a Web API. I have the below service definition for my Azure Cloud service.
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureWeb_ExternalCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<WebRole name="ExternalWebApplication" vmsize="A6">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
<Setting name="ServiceBaseURL" />
</ConfigurationSettings>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
</WebRole>
<WebRole name="InternalWebAPI" vmsize="Small">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint2" endpointName="Endpoint2" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
</ConfigurationSettings>
<Endpoints>
<InternalEndpoint name="Endpoint2" protocol="http" port="8080" />
</Endpoints>
</WebRole>
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint roleName="InternalWebAPI" endpointName="Endpoint2"/>
</Destinations>
<WhenSource matches="AnyRule">
<FromRole roleName="ExternalWebApplication"/>
</WhenSource>
<AllowAllTraffic/>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
However, I get the below error when I try to build.
The XML specification is not valid: The element 'OnlyAllowTrafficTo'
in namespace
'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition'
has invalid child element 'AllowAllTraffic' in namespace
'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition'
According to the ServiceDefinitionSchema (mine is located at %ProgramFiles%\Microsoft SDKs\Azure.NET SDK\v2.8\schemas), the AllowAllTraffic element must precede the WhenSource element.
I have spring basic authentication working on tomcat.
When I loaded the application on WebLogic 12c it suddenly stopped working, some research suggested I put <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials> in the config.xml file of the domain to stop WebLogic intercepting the AUTHENTICATE header.
It now works if I access via the ip address
//basic spring authentication works
http://123.456.789.111/mycontext
but not via localhost
//can no longer login to the application
http://localhost/mycontext
Does anyone know how I can fix this?
UPDATE - spring security configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 pattern="/resources/**" security="none"/>
<http pattern="/404" security="none"/>
<http auto-config="true">
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/endpoints/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_USER" />
<logout logout-success-url="/logout"/>
<form-login
login-page="/login"
authentication-failure-url="/login?login_error=1"
default-target-url="/dashboard"
always-use-default-target='true'/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="test" password="pass" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>