I have a problem to make sample which will fulfill RFC-7522. What I have is IdentityServer4 (v2.2.0) as oAuth Authorization Server (.NET Core 2.0, Console Application) and different SAML2 IdP. Now I want to use Saml Assertion to auth user.
As inspiration I used this video where Brock Allen and Dominick Baier describes how to set up SAML2 handler.
But sadly, I'm stuck right at beginning where I want just paste that snippet to my code and every time I end up with different compilation error (depends on nuget I use). I've unfortunately had no luck in solving them.
Snipet:
//IServiceCollection services
services.AddAuthentication().AddSaml2(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SPOptions.EntityId = new Saml2NameIdentifier(samlIdentityUrl);
var idp = new IdentityProvider(new EntityId(samlMetadataUrl), options.SPOptions)
{
SingleSignOnServiceUrl = new Uri(samlSignOnUrl),
Binding = Saml2BindingType.HttpRedirect
};
idp.SigningKeys.AddConfiguredKey(new X509Certificate2(certificate));
options.IdentityProviders.Add(idp);
});
Common Nugets:
IdentityModel.Unoficial (2.8.1)
IdentityServer4 (2.2.0)
Microsoft.AspNetCore.All (2.0.3)
Microsoft.IdentityModel.Tokens.Saml (5.2.4)
Sustainsys.Saml2.AspNetCore2 (see below)
Scenario #1: Sustainsys.Saml2.AspNetCore2 (0.24.0)
Package 'Sustainsys.Saml2.AspNetCore2 0.24.0' was restored using '.NetFramework, Version=v4.6.1'.. what is referred in this and this issue. On top of that I have few compilation error which could be break to 'The type 'EntityId' and 'SecurityKeyIdentifierClause' is defined in an assembly that is not referenced.'
Scenario #2: Sustainsys.Saml2.AspNetCore2 (2.0.0-preview01)
Missing whole Sustainsys namespace and it is replaced by Kentor.AuthServices. Reference .AddSaml2(..) not found.
Fine, I was able to solve my problem by update nugets and imports to following state:
Nugets:
IdentityServer4 (2.2.0)
Microsoft.AspNetCore.All (2.0.3)
Microsoft.IdentityModel.Token.Saml (5.2.4.)
Sustainsys.Saml2 (2.0.0-preview01)
Sustainsys.Saml2.AspNetCore2 (2.0.0-preview01)
Imports:
using Microsoft.IdentityModel.Tokens.Saml2;
using Kentor.AuthServices;
using Kentor.AuthServices.Metadata;
using Kentor.AuthServices.WebSso;
Related
I found strange behavior during checking functionality of WSO2 AM + IS as key manager.
Env I:
WSO2 AM 3.2.0 (GA pack)
Env II:
WSO2 AM 3.2.0 (GA pack)
WSO2 IS 5.10.0 (GA pack)
Configuration:
created users: user-low, user-high
created roles: low, high
user-low has assigned low role
user-high has assigned high role
created shared scopes: high-scope, low-scope
high-scope pointed to high role
low-scope pointed to low role
published api with 2 endpoint
/unsecure (has pointed scope: low-scope)
/secured (has pointed scope: high-scope)
Behaviour on ENV I (working fine - expected behaviour):
After trying generate token by "user-high" with scopes high-scope, low-scope as a receive on endpoint: https://localhost:9443/generate-token
response:
{
"accessToken":"eyJ4NXQiOiJNell4TW1Ga09HWXdNV0kwWldObU5EY3hOR1l3WW1NNFpUQTNNV0kyTkRBelpHUXpOR00wWkdSbE5qSmtPREZrWkRSaU9URmtNV0ZoTXpVMlpHVmxOZyIsImtpZCI6Ik16WXhNbUZrT0dZd01XSTBaV05tTkRjeE5HWXdZbU00WlRBM01XSTJOREF6WkdRek5HTTBaR1JsTmpKa09ERmtaRFJpT1RGa01XRmhNelUyWkdWbE5nX1JTMjU2IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJ1c2VyLWhpZ2hAY2FyYm9uLnN1cGVyIiwiYXV0IjoiQVBQTElDQVRJT04iLCJhdWQiOiIxeXZfaUZ2d3RvZmZ4RU90ZlJGZmpseGNjNG9hIiwibmJmIjoxNjEyMzU3NTExLCJhenAiOiIxeXZfaUZ2d3RvZmZ4RU90ZlJGZmpseGNjNG9hIiwic2NvcGUiOiJISUdIIGFtX2FwcGxpY2F0aW9uX3Njb3BlIiwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2VuIiwiZXhwIjoxNjEyMzYxMTExLCJpYXQiOjE2MTIzNTc1MTEsImp0aSI6ImQ3OTQ3ODc0LTRlNTMtNGI1My1iMWUwLTE0NGEwYTY2MDU5ZSJ9.KBol5clfIxScVPYVzdmBkz0APaE7uL8genldz8tx_G0FnaJStjn0tizDQfdcc46ZaEC1ahEfsGqBea6sJ8dpFucpf3ZqxnCz7CoJnVLU5F4lAXm_C3imWhOWLxF_wka0dlGExPDBpXQOmnspe2b45DSpIpz3zbTnnuClFM91tJkWrG9-k_ZIUHikI34m3aWltotXJzQJojdhL42pUCCttGcNGDbU9vfZ4wOcRx4fiVe6z0azvDBGP3FBSY00HyBFUo7ME9dqMaU_EDTybk77uLHyNGoQggOO42WU0ZfanrGlsYJSuzyQi4VVW3V1Uy6591b18LA28zq1c9Ay2-aMXw",
"tokenScopes":[
"HIGH",
"am_application_scope"
],
"validityTime":3600
}
Behaviour on ENV II:
After trying generate token by "user-high" with scopes high-scope, low-scope as a receive on endpoint: https://localhost:9443/generate-token
response:
{
"accessToken":"eyJ4NXQiOiJNell4TW1Ga09HWXdNV0kwWldObU5EY3hOR1l3WW1NNFpUQTNNV0kyTkRBelpHUXpOR00wWkdSbE5qSmtPREZrWkRSaU9URmtNV0ZoTXpVMlpHVmxOZyIsImtpZCI6Ik16WXhNbUZrT0dZd01XSTBaV05tTkRjeE5HWXdZbU00WlRBM01XSTJOREF6WkdRek5HTTBaR1JsTmpKa09ERmtaRFJpT1RGa01XRmhNelUyWkdWbE5nX1JTMjU2IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJ1c2VyLWhpZ2hAY2FyYm9uLnN1cGVyIiwiYXV0IjoiQVBQTElDQVRJT04iLCJhdWQiOiJHU1RYeVdhNlNCeHRNRWhiVF91SnA4ZmtBNUlhIiwibmJmIjoxNjEyMzU3MDQ5LCJhenAiOiJHU1RYeVdhNlNCeHRNRWhiVF91SnA4ZmtBNUlhIiwic2NvcGUiOiJISUdIIExPVyIsImlzcyI6Imh0dHBzOlwvXC9sb2NhbGhvc3Q6OTQ0M1wvb2F1dGgyXC90b2tlbiIsImV4cCI6MTYxMjM2MDY0OSwiaWF0IjoxNjEyMzU3MDQ5LCJqdGkiOiI0OTdhOTQ3OC0zZjg3LTQ0NmMtYjQ4OS1kMjI1MmQ2NDA2ZTYifQ.AoFKYLRsZBHELh8m0XBV0ndr19SMl0xMwzACG5-Q_ek7VRtWmocqJeAEjrXguUhcIUqHs843NPzcf185BpEjwCwJcXcR7ssIqxzINYSH0s7_LTm4X7XHMxV4cnF8gAiRnUQhGZQHgCyWI6NJ5VAcpIde5BnWaVcmx2Q5VFOFXGskfOB7325LcmhMS13Ni5oK2vb7YcTs059Zhoj13MrRnAOKoE1xrO9ioSVBXj9oX5RZ2uvdT_V3FQNWklc5jdMgebHDUQw-q_C5q9qhlGRZKql2ktcJ3OUeyGnJYEppuM0tOKCSTeH93MNcf6TAXYWEiRioa0FhRJblrfCIQrsHvA",
"tokenScopes":[
"HIGH",
"LOW"
],
"validityTime":3600
}
It's looks like in ENV II generating tokens not working properly. There is my questions:
Is it a bug of that versions or some misconfiguration issues?
If it's bug where i should start to try fix that situation, someone could point me where is implemented that functionality? (I want use opensource version over update products using WUM)
Is that situation was resolved in later versions of submodules, which are used to build product-api, and product-is?
Thanks in advance for any help and suggestions!
Trying to create a web client that uses oauth to connect to multiple sso endopints, google mainly. This is on top of a spring boot project, I just keep getting the same error that no code is provided, but I'm not sure how i'm supposed to get a code without the access token first. Here is a simple version of what im trying to run I want localhost/8080 to redir to google to login and comeback to the same page or a different one doesn't matter
#RequestMapping("/google")
fun google(#RequestParam(value = "code") code: String?, model: Model): String {
val clientId = "asdf.apps.googleusercontent.com"
val secret = "1234"
var goog = GoogleAuth.create(Vertx.factory.vertx(), clientId, secret)
goog.authenticate(JsonObject().put("code", code), {
System.out.println(it)
})
return "test"
}
the error is always
"error": "invalid_request",
"error_description": "Missing required parameter: code"
}}
e```
but how can I provide a code first I need some sort of response from the server. I'm pretty familiar with restful oauth and must be missing something
You can't use the GoogleAuth like that. GoogleAuth provides the basic primitives to handle the OAuth2 protocol. As you're not using the vertx-web part you will need to setup a callback endpoint in your application (I guess it's the /google endpoint you listed) but now you miss the whole Oauth2 handshake. Your client (browser) should call Google, which calls your server to validate the code.
So what you're asking here is to re-implement the vert.x web Oauth2Handler using Spring Boot APIs.
I have been trying to configure the oauth2 provider plugin in my grails application, but I am facing certain issues, and other than the plugin documentation, I didn't find any other sources that could help.
I have followed all the stepd mentioned in the doc, and made changes in Config.groovy
Now hitting localhost:8080/oauth/authorize?response_type=code&client_id=my-client&scope=read should redirect me to login page which it does.
After login however, I want authorization window to appear where user accepts or rejects granting authorization. I am however just getting a JSON result:
{"url":"http://localhost:8080/oauth/authorize?response_type=code&client_id=my-client&scope=read","success":true}
Why am I not getting an authorization prompt instead? What am I missing here?
Okay. So I have made some changes:
grails.plugin.springsecurity.filterChain.filterNames = [
'cookieSessionFilter',
'securityContextPersistenceFilter', 'statelessSecurityContextPersistenceFilter','logoutFilter',
'authenticationProcessingFilter','exceptionTranslationFilter', 'oauth2ProviderFilter', 'clientCredentialsTokenEndpointFilter',
'oauth2BasicAuthenticationFilter', 'securityContextHolderAwareRequestFilter',
'rememberMeAuthenticationFilter','anonymousAuthenticationFilter', 'oauth2ExceptionTranslationFilter', 'filterInvocationInterceptor'
]
grails.plugin.springsecurity.filterChain.chainMap = [
'/oauth/token': 'JOINED_FILTERS, -cookieSessionFilter, -oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter' ,
'/securedOAuth2Resources/**': 'JOINED_FILTERS,-cookieSessionFilter, -securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter'
]
Just proper ordering of filters seems to be solving the problem.
With this configuration I am able to generate the access_token.
In my implementation I am using OpenID-Connect Server (Identity Server v3+) to authenticate Asp.net MVC 5 app (with AngularJS front-end)
I am planning to use OID Code flow (with Scope Open_ID) to authenticate the client (RP). For the OpenID connect middle-ware, I am using OWIN (Katana Project) components.
Before the implementation, I want to understand back-channel token request, refresh token request process, etc using OWIN.. But I am unable to find any documentation for this type of implementation (most of the available examples use Implicit flow).
I could find samples for generic Code flow implementation for ID Server v3 here https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source
I am looking for a similar one using OWIN middleware ? Does anyone have any pointers ?
Edit: good news, code flow and response_mode=query support was finally added to Katana, as part of the 4.1 release (that shipped in November 2019): https://github.com/aspnet/AspNetKatana/wiki/Roadmap#410-release-november-2019.
The OpenID Connect middleware doesn't support the code flow: http://katanaproject.codeplex.com/workitem/247 (it's already fixed in the ASP.NET 5 version, though).
Actually, only the implicit flow (id_token) is officially supported, and you have to use the response_mode=form_post extension. Trying to use the authorization code flow will simply result in an exception being thrown during the callback, because it won't be able to extract the (missing) id_token from the authentication response.
Though not directly supported, you can also use the hybrid flow (code + id_token (+ token)), but it's up to you to implement the token request part. You can see https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Nancy/Nancy.Client/Startup.cs#L82-L115 for an example.
The answer and comment replies by Pinpoint are spot on. Thanks!
But if you are willing to step away from the NuGet package and instead run modified source code for Microsoft.Owin.Security.OpenIdConnect you can get code (code) flow with form_post.
Of course this can be said for all open source project problems but this was an quick solution for a big thing in my case so I thought I'd share that it could be an option.
I downloaded code from https://github.com/aspnet/AspNetKatana, added the csproj to my solution and removed lines from https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs in AuthenticateCoreAsync().
You must then combine it with backchannel calls and then create your own new ClaimsIdentity() to set as the notification.AuthenticationTicket.
// Install-Package IdentityModel to handle the backchannel calls in a nicer fashion
AuthorizationCodeReceived = async notification =>
{
var configuration = await notification.Options.ConfigurationManager
.GetConfigurationAsync(notification.Request.CallCancelled);
var tokenClient = new TokenClient(configuration.TokenEndpoint,
notification.Options.ClientId, notification.Options.ClientSecret,
AuthenticationStyle.PostValues);
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
notification.ProtocolMessage.Code,
"http://localhost:53004/signin-oidc",
cancellationToken: notification.Request.CallCancelled);
if (tokenResponse.IsError
|| string.IsNullOrWhiteSpace(tokenResponse.AccessToken)
|| string.IsNullOrWhiteSpace(tokenResponse.RefreshToken))
{
notification.HandleResponse();
notification.Response.Write("Error retrieving tokens.");
return;
}
var userInfoClient = new UserInfoClient(configuration.UserInfoEndpoint);
var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
if (userInfoResponse.IsError)
{
notification.HandleResponse();
notification.Response.Write("Error retrieving user info.");
return;
}
..
I am trying to integrate CAS into our web application to authenticate via OAuth 2.0, and i have downloaded the demo application from "https://github.com/leleuj/cas-oauth-demo-3.5.x."(client demo). and deployed it in tomcat7, but exception is thrown when authenticate with Google account. i have tried to write another provider and authentication is ok, but can not be redirected to my original web page.
Below is the error message. Does anyone be familar with CAS Oauth? look forward to your answers, thanks.
{"failure":"true","exception.message":"org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.jasig.cas.support.oauth.web.flow.OAuthAction#1077092 in state 'oauthAction' of flow 'login' -- action execution attributes were 'map[[empty]]'","exception.stacktrace":"org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing org.jasig.cas.support.oauth.web.flow.OAuthAction#1077092 in state 'oauthAction' of flow 'login' -- action execution attributes were 'map[[empty]]'\r\n\tat org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:60)\r\n\tat org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77)\r\n\tat org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)\r\n\tat org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)\r\n\tat org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)\r\n\tat org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)\r\n\tat org.springframework.webflow.engine.State.enter(State.java:194)\r\n\tat org.springframework.webflow.engine.Flow.start(Flow.java:535)\r\n\tat org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:366)\r\n\tat org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:225)\r\n\tat org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)\r\n\tat org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:193)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:621)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:722)\r\n\tat org.jasig.cas.web.init.SafeDispatcherServlet.service_aroundBody2(SafeDispatcherServlet.java:128)\r\n\tat org.jasig.cas.web.init.SafeDispatcherServlet.service_aroundBody3$advice(SafeDispatcherServlet.java:57)\r\n\tat org.jasig.cas.web.init.SafeDispatcherServlet.service(SafeDispatcherServlet.java:1)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)\r\n\tat org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)\r\n\tat org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat com.github.inspektr.common.web.ClientInfoThreadLocalFilter.doFilter(ClientInfoThreadLocalFilter.java:63)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)\r\n\tat org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)\r\n\tat org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)\r\n\tat org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)\r\n\tat org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)\r\n\tat java.lang.Thread.run(Thread.java:662)\r\nCaused by: java.lang.NullPointerException\r\n\tat org.jasig.cas.support.oauth.web.flow.OAuthAction.doExecute(OAuthAction.java:93)\r\n\tat org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)\r\n\tat org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)\r\n\t... 45 more\r\n"}
I'm the creator of the OAuth support for CAS. Google OAuth 1.0 support has been removed by Google. You have to switched to Google OAuth 2.0 support by using the Google2Provider class.