ASP.Net Identity with SAML Integration - asp.net-mvc

We have an existing MVC app using the ASP.Net Identity Framework to store user logins/passwords/roles/etc... in a local SQL database. We would like to move the authentication portion of the identity to use a SAML IdP but still build out the IdentityUser object within the Identity Framework with the details from the local database. Essentially the flow would be:
User browses to site -> User is forwarded to IdP for authentication -> User is directed back to site after successful authentication -> Details from local SQL database are retrieved using information passed back from IdP (likely email address) -> Site leverages IdentityUser object with information from local database
I cannot find really any information on this approach, which makes me think it is not possible and/or advisable. Any direction or suggestions would be appreciated.

You could handle the AcsCommandResultCreated notification and then load the IdentiyUser by the email saml assertion

Related

IdentityServer4 Usermanagement with separate MVC Client (AspNetIdentity)

After a lot of reading and trial and error I got my target design working:
IdentityServer4 (standalone with AspNetIdentity) with IdentityUser database
MVC Client (standalone), this is the frontend to the users, no database link at the moment
1-n WebAPIs which serve the functionality to the MVC Client and have their own databases
At the moment I use an already existing IdentityUser database and point the IS4 to this database, added roles and claims manually for testing purpose.
My question is about best practice to register new users.
As the MVC Client is the frontend to the user, a link to the user registration should appear here.
But where is the registration technically done?
Should I do it in the MVC Client (with the default IdentityUser Registration) and point the database to the IS4 database or
should I add a register function in the IS4 app to keep the MVC Client free of any database dependencies and point the MVC Client "register" link to this IS4 register function?
Basically IdentityServer has two responsibilities:
Authenticate the user
Authorize the client
The 'problem' with IdentityServer is that the user is not restricted to one application. While the MVC website may be your front, IdentityServer does not relate users to a particular application. Once authenticated, the user can access all applications that use IdentityServer as an authentication server.
So does it make sense to register the user on the MVC website? Probably not, because the user can access the (future) 'mvc2' website as well.
The creators of IdentityServer acknowledged this, so they created the PolicyServer:
We think that tightly coupling "Identity and Access Management" in a
single solution is the wrong approach. These two concerns should be
clearly separated.
In other words: authentication is part of IdentityServer, authorization (of the user) is not.
Getting back to the question, registration of the user should be managed by IdentityServer. Because that is the only application that has access to the Identity store. Besides, users can also register without being redirected by an application.
The key is how to manage the authorization (of the user). This isn't actually part of IdentityServer. I won't go into detail as this is outside the scope of the question.
But to answer your question, what I would do (including email verification, but without automatic login):
Add registration functionality to the IdentityServer and implement a ReturnUrl (like is already the case for login).
Add a link on your mvc website to the register function on IdentityServer. Let the user register in IdentityServer, send an email verification link which sends the user to the login page (persisting the return url), allowing the user to redirect back to the mvc website once registered and logged in.
How to add authorization to the registered user is a different question.
I would not use "User Management" and "User Registration" interchangeably. There is a lot more to user management than just registration. But to answer your question:
Should I do it in the MVC Client (with the default IdentityUser
Registration) and point the database to the IS4 database or
You could, and there would not be anything terribly wrong with that. This will heavily depend on your business requirements, but most often I have seen "User Registration" built into the identity providers (your IdentityServer4 in this case).

Identity Server 3 ADFS and Asp.Net Identity 2.0

Looking for a bit of advice regarding best practice regarding multiple user stores.
Currently I have Identity Server 3 set up using a factory method to connect to an Asp.Net Identity V2 user store.
I have two MVC Relying Party applications, both using OWIN to pass un-authenticated requests to the Identity Server.
Within Identity Server, both RP client applications are set up using Hybrid flow.
Now my question:
I want to have the Identity Server use mutiple user stores (in my case, we have users authenticating via our Identity V2 Store and also via ADFS)
I'm not sure how to detect or tell the which kind of user is connecting to the RP client application, and I'm not sure how to pass this information to Identity Server so that it can make a decision on which user store to use.
Any help greatly appreciated.

Simple way to authenticate users in ASP.NET MVC without providers

I'm trying to understand how authentication in ASP.NET MVC works. I do not want the built-in MembershipProvider creating a local database behind the scenes. I've also looked at some blog posts talking about custom membership providers. While looking for a much simpler forms authentication model, I found the following:
FormsAuthentication.SetAuthCookie("myusername", true);
FormsAuthentication.SignOut();
The idea is to send the username and salted hashed password to the database and see if they match a record in there. If the user exists, then I pass the username to SethAuthCookie. My questions are:
Should the username be encrypted?
What happens if there are multiple servers and the user is surfing the website? I believe any one of the servers can serve content to the user, so how do they know if the user has been authenticated?
What's the preferred way of authenticating users in MVC without providers? Am I on the right track or should I be looking into something else?
Should the username be encrypted?
No.
What happens if there are multiple servers and the user is surfing the
website? I believe any one of the servers can serve content to the
user, so how do they know if the user has been authenticated?
At each request the server reads the authentication cookie that is sent by the client browser and which was generated by the FormsAuthentication.SetAuthCookie call, decrypts it and retrieves the username that is stored inside. Just make sure that you have set the same machine keys for all nodes of your server farm so that no matter which node emitted the authentication cookie, all other nodes can decrypt it.
What's the preferred way of authenticating users in MVC without
providers? Am I on the right track or should I be looking into
something else?
You are on the right track. You use the FormsAuthentication.SetAuthCookie method to emit the authentication cookie once you have verified that the password hash matches the one of the user in the database and in subsequent actions you could use the User.Identity.Name property to retrieve the currently authenticated user.
I would also recommend you checking out the following article which provides a good overview of how forms authentication works in ASP.NET.

DB access denied with ASP.Net MVC application after switching to windows authentication mode

I have a MVC application that I am now trying to add authentication and authorization to.
I want to allow users to get to the site and be automatically authenticated. So I set authentication mode="Windows" in the web.config, and enabled NTLM in the project options. The site now shows my domain name in the top right when I run it, but when I hit a action than needs DB access, it tells me access is denied for my user-name?
What step am I missing?
This is not necessarily an IIS or Windows Authentication issue. I would assume that your connection string looks something like this
Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI;
Now that you are using Windows authentication, the Domain\username is being passed to SQL to authenticate to the database. If you do not have the entire domain (or at least the subset logging into your application) as valid users in SQL, then you will get an unauthorized exception. You will need to a) pass a username/password to SQL in the conneciton string as below or b) add the users of your application to the security users of the database or c) use the impersonate attribute in the web.config file to impersonate a user that has access to both the application files on the web server and the database
SQL connection string with username/password
Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;
This is the subtle difference between authentication and authorization.
Authentication is the act of identifying who the user is (And you've done this bit)
Authorisation is the act of determining who is allowed to do what (You need to apply the appropriate access permissions to the database, for each of your users/roles)
The subject of database access permissions is a little to complicated for sensible coverage on this forum, so i suggest that you do a bit of research via Google, etc

Active and Passive Federation in WIF

I am trying to understand the difference between Active and Passive federation in WIF. It appears that one would use an Active Federation if the Relying Party (RP) is a WCF Service instead of an ASP.NET application and a Passive Federation if the RP is an ASP.NET application. Is this accurate?
So, in a scenario in which an ASP.NET application uses a WCF in the backend, the MS articles suggest using a 'bootstrap' security token that is obtained by the ASP.NET app using an ActAs STS and this token is used to authenticate with the WCF. In this scenario, it appears that we are doing a combination of Active (user -> STS -> ASP.NET RP) and Passive (ASP.NET -> ActAs STS -> WCF) Federation?
Active Federation is about authenticating user using WSTrust protocols and your Relying Party is who owns login window and asks for security token to STS.
Passive Federation is when Relying Party has no login logic and you are redirected to the login page located on STS. Active Federation is more complex to configure, in my opinion (I'm working with silverlight, so it needs some tricks). I'm planing to post about this subject on my blog, because there is little information about it on internet.
In short, Passive Federation is just a phrase used to represent the scenario that your browser is redirected to a login page hosted by the STS. After login the STS redirects you back to the referring URL with some cookie, or something, and you are authenticated at the site that trusts the STS (using thumbprints, certs, encryption,etc).
You don't have to do it that way either. I for example like my ASP.NET sites to actively contact the STS using credentials supplied by the user, but it means the ASP.NET app pool has to authenticate at the STS using Windows Auth in order to send the credentials supplied by the user to get a token, and then I explicitly add the token to the session. In other words I don't used Passive Federation, but that's just a choice.
You can read more about passive claims here:
http://garymcallisteronline.blogspot.co.uk/2012/11/claims-explained.html
An Active call is a direct call to a WSActive endpoint (these support many authentication types).. The following code shows an active call using the username active endpoint.
private static GenericXmlSecurityToken GetToken(string username, string password, string url, string audienceUrl)
{
var factory = new WSTrustChannelFactory(new Microsoft.IdentityModel.Protocols.WSTrust.Bindings.UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress(url));
factory.Credentials.UserName.UserName = username;
factory.Credentials.UserName.Password = password;
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.TrustVersion = TrustVersion.WSTrust13;
WSTrustChannel channel = null;
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(audienceUrl),
KeyType = WSTrust13Constants.KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
return channel.Issue(rst) as GenericXmlSecurityToken;
}
Even i had same problem initially but the this blog helped me a lot.
i would suggest you to go through samples first and then analyse the documentation.
WCF federation is tricky though.

Resources