How to use Sustainsys.Saml2.AspNetCore2 in existing net core app? - sustainsys-saml2

I'm trying to use Sustainsys.Saml2 and Sustainsys.Saml2.AspNetCore2 library provided by this saml2 library to implement both IDP initiated and SP initiated scenarios.
After referring sample appliation things I did so far:
1. Refer latest Sustainsys.Saml2.AspNetCore2 and Sustainsys.Saml2 via nuget
2. Modified Startup.cs to add new options
3. Created MVC controller with ACS end point
Things I'm trying to understand:
1. Do I need to Initiated Saml2Handler so that I can hit HandleRequestAsync() end point of library.
2. How to retrive principal/claims
3. For sp initiated case when end point identifies request is not authenticated how to redirect request to IDP?
ConfigureServices method in startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddSaml2(options =>
{
options.SPOptions.EntityId = new EntityId("https://localhost:3131/Saml2");
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId("http://localhost:52071/Metadata"), options.SPOptions)
{
LoadMetadata = true
});
options.SPOptions.ServiceCertificates.Add(new X509Certificate2("Sustainsys.Saml2.Tests.pfx"));
});
}
**SSO Controller**
[Authorize(AuthenticationSchemes = "Saml2")]
public class SsoController : Controller
{
public SingleSignOnController(ILogger logger)
{
}
[Route("saml2/ACS")]
[HttpPost]
public ActionResult ACS()
{
try
{
// Is request authenticated here by library?
// I tried hitting this end point from stud idp portal, but it is
throwing " MVC Exception Handler: The method or operation is not implemented. at Sustainsys.Saml2.AspNetCore2.Saml2Handler.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService"
}
catch (Exception e)
{
}
}
}
Do I need to create/implement Custom Saml2Handler and inject it in SSo controller? I could not find exact end point in this ASPNETSAMPLE project for saml2/ACS?
What I'm missing ?

The Acs endpoint is built into the handler. Remove your SsoController.
Check the asp.net core sample applications in the repo for an example on how to configure. The AspNetCore2 package contains a handler that works the same as any other external authentication handler for Asp.NET Core. You initiate the sign in sequence by an authentication challenge.

Related

How to Identify caller when grant_type is client_credentials?

I have ASP.NET Web application and I am using IdentityServer3 for user authentication. Our customers login to web application using userid/password.
Now I have one more Web API and some of our customers need to call this web api from their applications. (server to server communication). So based on this, in identityserver i did the following
1> Created a new scope name api
2> Created a new client for Web API and configured with allowed scope api and offline_access
3> Set flow to ClientCredentials
4> Set AccessTokenType to Jwt
5> For each customer i created different secret key
Now our customers can get access token at connect/token endpoint and then make call to API using the access token. The API validates the token with IdentityServer, and then returns the result. All good till here.
However, in API project i also need to identify the customer aka caller. Based on customer i need to do some logic
public class ResourcesController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal;
// need to identify caller here
return Json(new
{
message = "OK",
});
}
}
(One option i can think of is taking customer id is as part of API url. Something like http://api.domain.com/v1/customerid/resources)
Is there anyway to make a use of IdentityServer to identify customer?
I've actually had a similar need some time ago. For the simplest solution, you should be able to assign a custom claim to each of the Identity Server client that you have created for your customers.
AlwaysSendClientClaims = true,
Claims = new List<Claim>()
{
new Claim("CustomerId", "0121021")
}
These client claims will then be included in the access token and therefore available to you in your backend.
public class ResourcesController : ApiController
{
public IHttpActionResult Get()
{
var caller = User as ClaimsPrincipal;
// need to identify caller here
var customerId = caller?.Claims.Where(p => p.Type.Equals("CustomerId")).First().Value;
// need to identify caller here
return Json(new
{
message = "OK",
});
}
}

spring oauth and client credentials M2M calls

I have a front end website that is secured using spring-cloud-secuirty with spring-cloud-oauth2 . All my backend resources are secured using #EnableResourceServer .
All requests to these resources services coming from UI are authorized through the Zuul gateway, but my problem is with back end tasks that are scheduled to run on daily bases or the one are triggered by email. These tasks are not authorized and as I understood from reading they should be authenticated as client_credentials . But i am not able to figure out how to configure feign clients to get the access code before trying to communicate with secured resources.
I have created a sample project , in this project every thing is working except the task service
Adding the below interceptor did the trick but i am not sure this is the best solution
#Component
public class Interceptor implements RequestInterceptor {
private final OAuth2RestTemplate template;
public Interceptor(ClientCredentialsResourceDetails oauth2RemoteResource) {
template = new OAuth2RestTemplate(oauth2RemoteResource, new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
}
#Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("Authorization", "bearer " + template.getAccessToken().getValue());
}
}
Better Approach
After more reading I found that spring-cloud-security already have an interceptor so we just need to declare a bean of type OAuth2FeignRequestInterceptor as below
#Configuration
#EnableOAuth2Client
#Slf4j
public class OAuth2FeignAutoConfiguration {
#Bean
public OAuth2FeignRequestInterceptor oAuth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
return new OAuth2FeignRequestInterceptor(oauth2ClientContext,details);
}
}

Force ASP .Net Web API to block HTTP requests with Error (403)

I would like to configure my project to not allow http requests with the following restrictions:
It must be a global restriction for all APIs (via web.config, script in the installer, etc.)
It must be hard coded(not pressing "Require SSL" on the APP in the IIS)
No "redirect"- just return error (403)
my ideal option would be to configure "Require SSL" by a script which runs in the installer.
This can be accomplished by writing a simple ActionFilter that inspects the request and responds when the scheme is not set to ssl. A very minimal implementation may look something like:
public class RequireHttpsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
}
To make this apply everywhere, you'll likely want to register it as a global filter in the WebAPI configuration when your application is bootstrapping. That would look something like:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new RequireHttpsAttribute());
// ... More configuration ...
}
}
If you search the web a bit, you can find many examples of similar filters with more robust logic that may better meet your needs.

Keycloak Custom Validation Output messages

I'm using jboss keycloak 1.5 final version.
I developed my custom user federation provider interfacing with keycloak properties and my user enterprise database.
My need is to send up to user the login interface custom error messages based on particular specific error related to my legacy user db.
I saw keycloak themes have a resources folder by which i can localize and add new messages. Then i can reference them by angular js using
$myMessage
notation. The problem is i want to rise up a message from keycloak server. My user federation provider implements UserFederationProvider interface. So i should have to override:
#Override
public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential) {
LOGGER.info("validCredentials(realm, credential)");
return CredentialValidationOutput.failed();
}
which seems to be the method i was looking for just because CredentialValidationOutput contains custom messages to be sent as validation output. The problem is this method is never called.
Why?
I'll post the answer found on my own.
It's necessary to develop your own Authenticator. For example refer to Keycloak UsernameAndForm and UsernameAndFormFactory implementation.
You can find them on Keycloak github source code:
https://github.com/keycloak/keycloak/tree/master/services/src/main/java/org/keycloak/authentication/authenticators/browser
The main validation method are:
public boolean validateUserAndPassword(AuthenticationFlowContext context, MultivaluedMap<String, String> inputData) {
...
}
public boolean validatePassword(AuthenticationFlowContext context, UserModel user, MultivaluedMap<String, String> inputData) {
...
}
From your custom user federation provider you can throw your custom exception and catch them in the two methods above adding:
catch (YourCustomException ex){
...
Response challengeResponse = context.form()
.setError("YOUR ERROR MESSAGE", me.getMandator()).createLogin();
context.failureChallenge(AuthenticationFlowError.INVALID_USER, challengeResponse);
return false;
}
Of course in your project you have to add
META-INF/service/org.keycloak.authentication.AuthenticatorFactory
In which you specify the full qualified name of your AuthenticatorFactory.
For a valid guide make reference to Keycloak User Guide 1.6.1 Final. Chapter 33.3

OpenRasta - Scott Littlewoods Basic Authentication working example

I'm testing out the feasibility of using OpenRasta as a viable alternative to ASP.NET MVC.
However, I've run into a stumbling block regarding authentication.
Let me be clear, "Open Digest Authentication" is NOT an option at this point.
I've read that Scott Littlewood created a basic authentication fork for OpenRasta and I've downloaded the source from git and successfully built it.
I'm now trying to get the authentication working, so if someone has a real working model, I would be very grateful. Here's what I've done so far:
//Authentication.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using OpenRasta;
using OpenRasta.Configuration;
using OpenRasta.Authentication;
using OpenRasta.Authentication.Basic;
using OpenRasta.Configuration.Fluent;
using OpenRasta.DI;
namespace myOpenRastaTest.Extensions
{
public static class ExtensionsToIUses
{
public static void BasicAuthentication<TBasicAuthenticator>(this IUses uses) where TBasicAuthenticator : class, IBasicAuthenticator
{
uses.CustomDependency<IAuthenticationScheme, BasicAuthenticationScheme>(DependencyLifetime.Transient);
uses.CustomDependency<IBasicAuthenticator, TBasicAuthenticator>(DependencyLifetime.Transient);
}
}
public class CustomBasicAuthenticator : IBasicAuthenticator
{
public string Realm { get { return "stackoverflow-realm"; } }
public CustomBasicAuthenticator()
{
}
public AuthenticationResult Authenticate(BasicAuthRequestHeader header)
{
/* use the information in the header to check credentials against your service/db */
if (true)
{
return new AuthenticationResult.Success(header.Username);
}
return new AuthenticationResult.Failed();
}
}
}
Now to test it I just created an instance of CustomBasicAuthenticator in my HomeHandler.cs:
//HomeHandler.cs
using System;
using myOpenRastaTest.Resources;
namespace myOpenRastaTest.Handlers
{
public class HomeHandler
{
public object Get()
{
var custAuth = new myOpenRastaTest.Extensions.CustomBasicAuthenticator();
return new HomeResource();
}
}
}
So, I need to know what steps i need to take next, hence the reason for me asking for a real working model and not just theory answers since I've just stumbled upon the framework 2 days ago and might not know all the OpenRasta framework,RESTful lingo that you might throw back at me :)
Once I get a grasp of authentication, I'll have a good indication as to how to proceed with my evaluation of whether to port an existing asp.net prototype portal to OpenRasta or not.
Thanks in advance...
I have a sample application using the new OpenRasta authentication process that ONLY supports BASIC authentication at the moment.
Plugging in different authentication schemes should be quite straight forward but I haven't had the time recently to do this.
See this github discussion for future reference: https://github.com/scottlittlewood/openrasta-stable/commit/25ee8bfbf610cea17626a9e7dfede565f662d7bb#comments
For a working example checkout the code here: https://github.com/scottlittlewood/OpenRastaAuthSample
Hope this helps
Once you have an authentication in place, you need it to be triggered by having authorization on one of your resource handlers, which you can do by adding a RequiresAuthentication attribute on it for example.
You can have a look at the code for that attribute to see how to implement custom authorization yourself.