Spring security provide multiple authentication mechanisms - authentication

My RESTful webapplication needs to support multiple authentication mechanisms.
Which mechanism should be applied is not indicated by a specific URL but by using the client application name in a custom header field.
Each client application maps to a specific authentication mechanism.
Currently, we need to support the following:
Username / password authentication
LDAP auhtentication
OAuth2
We defined multiple authentication providers in the our spring-security.xml:
<authentication-manager>
<authentication-provider ref="daoAuthProvider" />
<authentication-provider ref="ldapAuthProvider" />
<authentication-provider ref="oAuth2Provider" />
</authentication-manager>
The problem is that the AuthenticationManager takes the first provider, tries to authenticate and executes the following provider in the chain when authentication fails.
But we 're fully aware which provider should be executed by our custom header field.
We could create a custom Authentication provider but this class doen't have a HttpServletRequest notion. So we're not able to read our custom header field and delegate to some provider accordingly.
Is there any other alternative to execute a specific provider based on a header field?

Related

OpenIddict 4 WebProviders does not configure external authentication schemes

I am just wondering if anyone has some experience with this. I am trying out OpenIddict 4.0.0 to put together a real-life solution with the new Identity UI and razor pages approach. However when I register an external auth provider using the suggested unified OpenIddict.Client.WebIntegration package, I cannot see the providers on the default login page external section.
I also tried to use the openiddict-core sandbox aspnet.core server app but that as well does not show the configured GitHub external login option.
I could explicitly create links for the providers, however I do not see that as a convenient solution. The default code segment that calls SignInManager.GetExternalAuthenticationSchemesAsync() does not seem to collect the external providers registered using
options.UseWebProviders().UseGitHub() ...
What am I missing here? Thanks
It's a deliberate design choice, explained in this post comparing the aspnet-contrib providers with the OpenIddict providers:
The aspnet-contrib providers use an authentication scheme per
provider, which means you can do [Authorize(AuthenticationSchemes = "Facebook")] to trigger an authentication dance. In contrast, the
OpenIddict client uses a single authentication scheme and requires
setting the issuer as an AuthenticationProperties item if multiple
providers are registered.
For the same reason, the providers registered via the OpenIddict
client are not listed by Identity's
SignInManager.GetExternalAuthenticationSchemesAsync() and so don't
appear in the "external providers" list returned by the default
Identity UI. In practice, many users will prefer customizing this part
to be more user-friendly, for instance by using localized provider
names or logos, which is not something you can natively do with
SignInManager.GetExternalAuthenticationSchemesAsync() anyway.

Using Openiddict for user identity management and application access

I have a .NET Core web API that uses openiddict for identity management that is tied to ASP.NET identity in a SQL server backend. Many applications can leverage this API with a subscription. I have the following requirements.
Only authorized applications can use the API
Each application can optionally use the identity features of the API to manage their application specific users as implemented by Openiddict within the API (currently the authorization, password, and refresh token flows are enabled).
All endpoints should require that an application be in the Oppenidict application table and this application ID should be available on every request due to multi-tenant support in the API.
Endpoints that have an [Authorize] attribute must be have a user that is authenticated via the Openiddict identity model.
To implement requirement (1), would I need to implement a custom authorization function that checks for an application secret or should another flow be enabled in openiddict that takes care of ensuring only authorized applications are allowed access to the API (regardless of authorize attributes)? In this case, a user may not be authenticated, but the application must still have rights to access the non-authorized endpoints of the API.
To implement requirement (2) for external identity providers, is it possible to configure multiple secrets for each application registered within openiddict to allow their users to leverage facebook or twitter for authentication? This is important, because the API would need call AddFacebook() during configuration for each application that can access the API (not the clientID and secret of the API itself). Because multiple applications each have their own facebookID and secret, I would assume this would only work if openiddict could allow the registration of multiple Ids and secrets for the same provider type via AddFacebook() for example.
To implement requirement (3), is there a built in way to get the application ID of the calling application from openiddict like there is if the user was authenticated?
To implement requirement (1), would I need to implement a custom authorization function that checks for an application secret or should another flow be enabled in openiddict that takes care of ensuring only authorized applications are allowed access to the API (regardless of authorize attributes)?
Starting with RC3, client identification was made mandatory by default: if you don't send a client_id corresponding to an entry in the applications table, your request will be rejected by OpenIddict itself. In previous versions, you could opt for this feature by calling options.RequireClientIdentification() (it's now opt-out).
To implement requirement (2) for external identity providers, is it possible to configure multiple secrets for each application registered within openiddict to allow their users to leverage facebook or twitter for authentication? This is important, because the API would need call AddFacebook() during configuration for each application that can access the API (not the clientID and secret of the API itself). Because multiple applications each have their own facebookID and secret, I would assume this would only work if openiddict could allow the registration of multiple Ids and secrets for the same provider type via AddFacebook() for example.
There's no direct relationship between OpenIddict and the authentication schemes you use, so no, you can't configure multiple Facebook credentials "via" OpenIddict as the two are unrelated.
Assuming you need that for multitenancy purposes, you may want to read https://stackoverflow.com/a/49682427/542757 to learn how you can override ASP.NET Core's default options monitor so you can provide tenant-specific options for authentication handlers like OpenIddict, Facebook, Google and anything else.
To implement requirement (3), is there a built in way to get the application ID of the calling application from openiddict like there is if the user was authenticated?
Assuming it's known (i.e you didn't explicitly make client identification optional in the OpenIddict options), yes. E.g from a MVC controller:
var result = await HttpContext.AuthenticateAsync(OpenIddictValidationDefaults.AuthenticationScheme);
Debug.Assert(result.Ticket != null, "The authentication ticket shouldn't be null.");
// The presenters list contains the authorized parties allowed to
// use the access token with your APIs. Usually, it contains a single value.
// Note: this extension requires a using for AspNet.Security.OpenIdConnect.Extensions.
var client = result.Ticket.GetPresenters().FirstOrDefault();

Custom authenticator for WSO2 IS

I'm trying to create a completely custom external authenticator for WSO2 IS. The idea is this:
1. A service provider forwards the user to WSO2 IS with a SAML2 request (Inbound authentication configuration = SAML2 Web SSO Configuration).
2. The local authentication configuration for said service provider is my custom authenticator.
3. The custom authenticator redirects the user to an authentication service.
4. The user logs in.
5. The login service forwards the user back to the WSO2 IS custom authenticator (using the same URL as before "/samlsso".
The problem is that the parameters used and returned by the login service are completely proprietary, ie. not SAML2. However, WSO2IS expects a SAML2 request when accessing the custom authenticator.
How can I create a custom authenticator which uses completely proprietary paramters towards the login service, but normal SAML2 towards the service provider?
In the step5, it should forward to the /commonauth endpoint. So, it will be identified the correct context from getContextIdentifier method in your authenticator.
You can use Facebook authenticator as an example [1]
[1] https://github.com/wso2/carbon-identity/blob/master/components/application-authenticators/org.wso2.carbon.identity.application.authenticator.social/src/main/java/org/wso2/carbon/identity/application/authenticator/social/facebook/FacebookAuthenticator.java

Custom Http Authorization Header with Spring Security

We are building a Restful service using Grails framework and are providing security for it using Spring Security plugin. I wanted to check with you all on best approach to take when you want to authenticate using Custom Authorization header. More on this approach can be read here
Custom HTTP Authorization Header
In my case, client id and secret is stored in Ldap and header comes with SHA1 encryption. What would be the best approach to implement this using Spring Security?
I have asked same question in Grails mailing list too.
Any insight would be helpful. Thanks.
~Abhi
You have to implement your own Filter, Authentication Provider and Authentication token (to pass data to your Provider).
See:
what is securty filter chain - http://static.springsource.org/spring-security/site/docs/3.0.x/reference/security-filter-chain.html
authentication providers - http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-services.html#core-services-dao-provider
how to register your filter into Spring Secutory Core plugin - http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/16%20Filters.html
and, if you need an example, take a look at some existing authentication subplugins for Spring Security Core - http://grails.org/plugin/spring-security-core
List item
If you are using basic authorization header, then following configuration works for you in context-security.xml file.
< http auto-config="true" use-expressions="true" pattern="/project/api/**">
< intercept-url pattern="/**" access="isFullyAuthenticated()" requires-channel="${security.requires.channel}" method="POST"/>
< custom-filter ref="basicAuthenticationFilter" position="PRE_AUTH_FILTER"/>
< /http>
< beans:bean id="basicAuthenticationFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
< beans:property name="authenticationManager" ref="authenticationManager" />
< beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
< /beans:bean>
I have used same approach for rest services But you need to be careful that whatever scheme you use for encoding username and password, same scheme you should use in filter for decoding 'Authorization' header information. If you are using some custom scheme for encoding 'Authorization' header, then you need to extend 'BasicAuthenticationFilter' and provide appropriate decoding of 'Authorization' header

Programmatic login (authentication) in WebLogic (JAAS)

We have an existing Java EE application running under WebLogic and I want to authenticate a user programmatically as though the user was logged in via the existing web login process. That is to say, in the end, I want to have a valid session (cookie) that can be returned to the caller and later returned back the server without re-authentication. (This is to enable JAX-WS stateful Web Service calls).
We have a custom LoginModule that, when the user logs in via Forms Authentication, is eventually called via j_security_check. I guess what I'd like to do is to somehow get WebLogic to invoke that LoginModule on my behalf, ask me for the credentials, and yield an authenticated session and a valid subject etc. (i.e. all the JAAS goodness).
Is this a JAAS thing? Is there a WebLogic call?
You can do this using the HttpServletRequest#login method. This will trigger the same kind of login chain that would otherwise be executed if your used accessed a protected resource.
WebLogic security uses a security service plug-in (SSPI) architecture that allows you to implement security providers. Container (such as servlet) authentication is handled by authentication providers that use the SSPI. An authentication provider wraps a JAAS login module.
Writing and configuring security providers is extensively documented.
If you implement an authentication provider to wrap your login module and configure it for the WebLogic domain, it will be called automatically by the WebLogic security framework for all container authentication.