Passing azure token across mvc applications - asp.net-mvc

I am working on an intranet application where we have multiple MVC web applications authenticating against azure ad using OpenId. All works well with the first MVC application which redirects to azure login page and get the claims back. I want this information to be passed to the downstream MVC applications without the user logging again. I am not sure how to implement it in the best way. I cannot find the information here as well. It will be great help if someone shares can it be done.

Since you're using OpenID, why not just pass the access_token and id_token downstream. Those are all you need, and in fact, you do not need the id_token unless you want additional user-profile data. You can store the tokens in the browser or where ever else is convenient, and then including them in each request for a secure resource.

Related

How can I include authentication in api endpoint in .NET 6 web app with identity

I have a ASP.NET Core 6 web app. I'm using Identity for an authentication. It is in its simplest form - users need to put credentials in the login page to access parts of aplication.
Now I need to expose one endpoint. It should be accessible by application from a different server. Therefore a solution with redirection to a login page and storing credential in caches doesn't make sense (keep in mind I want to keep it, just add some filtering on a particular api).
Instead I would prefer to allow hitting this enpoint with some kind of token. Another solution that comes to my mind is to whitelist the server of the application not to require authorization.
I don't know which of these are possible or recommended. Will gladly hear your advices.

How to handle authorization and authentication on SPA with OAuth2?

I am developing an SPA and would like to have SSO.
As I understood so far, OAuth2 with OIDC is the best solution for SPA SSO.
Better than, for example, SAML.
What I didn't understand so far is how to use authorization token in SPA's JS code to handle authorization on various resources of SPA. For example, I would like the users with a role 'buyer' to have access to the shopping history tab, where other users won't have access to.
Should I parse access token obtained from Authorization server in JS code and check whether a user has an appropriate role to see the tab, or should this decision be made on server (API) side, in which case SPA's code would just read the answer from API and based on that customize UI?
In case of the first approach, is there any standard way of doing the checking (in form of some JS library)?
When it comes to authentication, what is the better approach (more secure, etc):
to let SPA (at that point already loaded in the browser) do the authentication flow and based on result let the user use it's protected functionalities. This is pseudo authentication actually since the code is in the user's browser and means the user is authenticating himself to the code in his hands i.e. to himself. Does this authentication make sense at all?
require the user to authenticate himself in order to be able to even load the SPA in his browser. This is probably not SPA architecture then since backend which serves the SPA should be able to create a backchannel with the Authentication server.
According to user description, your application must vary depending on user type. If this is the case I would suggest you to use a backend for authentication and decide application content to be served from the backend. Otherwise, as you have figured out, running authentication on browser and altering user view is not secure.
IMO this not necessarily break SPA architecture. What you are doing is altering what you server based on tokens presented to you. Also, maintaining a session will be required with this approach. And SPA's calls for backend will require to contain this session to obtain contents.
As soon as the User is logged in, you would request for authentication and based on his UserId, and the role he belongs to you should receive all the permissions that User is entitled to.
You convert these permissions into claims and can send them back to UI and use it appropriately to show the features accordingly.
You also enforce same on the server side api to prevent any unauthorized access besides from your UI.

ASP.NET Application - Restrict Microsoft Authentication subscribers

I have an ASP.NET application hosted as Azure App Service. This application is configured with Microsoft Authentication. But the problem is anyone with hotmail/live account will be able to access the application.
I wanted to restrict the access to my Application Pages to SPECIFIC hotmail/live users only.
What changes I have to do on Azure Portal?
What changes I have to do in my application?
Thanks,
Paraclete
Applications typically have two "gates" of security - authentication and authorisation.
The simplest way would be to set up a list in a store (e.g. SQL DB - or hard code for testing) of authorised users. Let the Microsoft Authentication handle authentication and then use your list for authorisation. Redirect to HTTP Status code 403 forbidden if a user is not in the list of approved users.
You could make this a bit more fancy by implementing groups/roles, which is more elegant and manageable. Look in to the ASP.NET Role provider for built in functionality to expedite development. That said, some people find this build in approach cumbersome and roll their own simple provider and add it in to the page life cycle or the master page to share the functionality across all pages.

ASP.NET MVC 2 and authentication using WIF (Windows Identity Foundation)

Are there any decent examples of the following available:
Looking through the WIF SDK, there are examples of using WIF in conjunction with ASP.NET using the WSFederationAuthenticationModule (FAM) to redirect to an ASP.NET site thin skin on top of a Security Token Service (STS) that user uses to authenticate (via supplying a username and password).
If I understand WIF and claims-based access correctly, I would like my application to provide its own login screen where users provide their username and password and let this delegate to an STS for authentication, sending the login details to an endpoint via a security standard (WS-*), and expecting a SAML token to be returned. Ideally, the SessionAuthenticationModule would work as per the examples using FAM in conjunction with SessionAuthenticationModule i.e. be responsible for reconstructing the IClaimsPrincipal from the session security chunked cookie and redirecting to my application login page when the security session expires.
Is what I describe possible using FAM and SessionAuthenticationModule with appropriate web.config settings, or do I need to think about writing a HttpModule myself to handle this? Alternatively, is redirecting to a thin web site STS where users log in the de facto approach in a passive requestor scenario?
An example of WIF + MVC is available in this chapter of the "Claims Identity Guide":
http://msdn.microsoft.com/en-us/library/ff359105.aspx
I do suggest reading the first couple chapters to understand all underlying principles. This blog post covers the specifics of MVC + WIF:
Link
Controlling the login experience is perfectly fine. You should just deploy your own STS (in your domain, with your look & feel, etc). Your apps would simply rely on it for AuthN (that's why a app is usually called a "relying party").
The advantage of the architecture is that authN is delegated to 1 component (the STS) and not spread out throughout many apps. But the other (huge) advantage is that you can enable more sophisticated scenarios very easily. For example you can now federate with other organization's identity providers.
Hope it helps
Eugenio
#RisingStar:
The token (containing the claims) can be optionally encrypted (otherwise they will be in clear text). That's why SSL is always recommended for interactions between the browser and the STS.
Notice that even though they are in clear text, tampering is not possible because the token is digitally signed.
That's an interesting question you've asked. I know that for whatever reason, Microsoft put out this "Windows Identity Foundation" framework without much documentation. I know this because I've been tasked with figuring out how to use it with a new project and integrating it with existing infrastructure. I've been searching the web for months looking for good information.
I've taken a somewhat different angle to solving the problem you describe.
I took an existing log-on application and integrated Microsoft's WIF plumbing into it. By that, I mean that I have an application where a user logs in. The log-on application submits the credentials supplied by the user to another server which returns the users identity (or indicates log-on failure).
Looking at some of Microsoft's examples, I see that they do the following:
Construct a SignInRequestMessage from a querystring (generated by a relying party application), construct a security token service from a custom class, and finally call FederatedSecurityTokenServiceOperations.ProcessSignInresponse with the current httpcontext.response. Unfortunately, I can't really explain it well here; you really need to look at the code samples.
Some of my code is very similar to the code sample. Where you're going to be interested in implementing a lot of your own logic is in the GetOutputClaimsIdentity. This is the function that constructs the claims-identity that describes the logged-in user.
Now, here's what I think you're really interested in knowing. This is what Microsoft doesn't tell you in their documentation, AFAIK.
Once the user logs in, they are redirected back to the relying party application. Regardless of how the log-on application works, the WIF classes will send a response to the user's browser that contains a "hidden" HTML input that contains the token signing certificate and the user's claims. (The claims will be in clear text). At the end of this response is a redirect to your relying-party website. I only know about this action because I captured it with "Fiddler"
Once back at the relying party web site, the WIF classes will handle the response (before any of your code is run). The certificate will be validated. By default, if you've set up your relying party web site with FedUtil.exe (by clicking "Add STS Reference in your relying party application from Visual Studio), Microsoft's class will verify the certificate thumbprint.
Finally, the WIF framework sets cookies in the user's browser (In my experience, the cookie names start out with "FedAuth") that contain the users claims. The cookies are not human readable.
Once that happens, you may optionally perform operations on the user's claims within the relying party website using the ClaimsAuthenticationClass. This is where your code is running again.
I know this is different from what you describe, but I have this setup working. I hope this helps!
ps. Please check out the other questions I've asked about Windows Identity Foundation.
UPDATE: To answer question in comment below:
One thing that I left out is that redirection to the STS log-on application happens by way of a redirect with a query-string containing the URL of the application the user is logging in to. This redirect happens automatically the first time a user tries to access a page that requires authentication. Alternatively, I believe that you could do the redirect manually with the WSFederationAuthentication module.
I've never tried to do this, but if you want to use a log-on page within the application itself, I believe the framework should allow you to use the following:
1) Encapsulate your STS code within a library.
2) Reference the library from your application.
3) Create a log-on page within your application. Make sure that such page does not require authentication.
4) Set the issuer property of the wsFederation element within the Microsoft.IdentityModel section of your web.config to the login page.
What you want to do is an active signin. WIF includes WSTrustChannel(Factory) which allows you to communicate directly with the STS and obtain a security token. If you want your login form to work this way, you can follow the "WSTrustChannel" sample from the WIF 4.0 SDK. Once you have obtained the token, the following code will take that token and call the WIF handler to create a session token and set the appropriate cookie:
public void EstablishAuthSession(GenericXmlSecurityToken genericToken)
{
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(
new StringReader(genericToken.TokenXml.OuterXml)));
var identity = handlers.ValidateToken(token).First();
// create session token
var sessionToken = new SessionSecurityToken(
ClaimsPrincipal.CreateFromIdentity(identity));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
Once you have done this, your site ought to behave the same as if passive signing had occurred.
You could use the FederatedPassiveSignIn Control.
Setting your cookie like this:
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
Doens't work for SSO to other domains.
To cookie should be set by the STS not at the RP.

ASP.NET MVC multi-site SSO using OpenID

I am putting a plan together for a series of sites that will share user account information among them. The idea is that once a user logs in using their OpenID, they can access any of the sites and it will know who they are.
What are the common patterns/best practices that i could employ to achieve this?
If all the sites share a common hostname in their URL then you can set an auth cookie (FormsAuthentication.SetAuthCookie) specifying the path of the cookie to be "/" so that all sites can see the user is logged in.
If the sites are not sharing a common host name, I think the only way to get a truly "once signed in, signed in everywhere [within your ring of web sites]" would be for all authentication to happen at just one site (perhaps one dedicated to authenticating the user) and for the other sites to redirect the user to that site for authentication and then that site would redirect back. In essence, that auth site becomes an identity provider, and almost exactly fills the role of an OpenID Provider (in fact DotNetOpenAuth could be used here for this exact purpose). Since it sounds like your goal is to let the user log in with their OpenID, your OpenID Provider on that one auth site could itself use OpenID to authenticate the user. Your own pure-delegation OpenID Provider could be written such that it always responds immediately to checkid_immediate requests as long as the Realm in the auth request is one of your trusted ring of sites. Thus you could effect single-sign-on across all your sites.
Please consider the following Patterns & Practices on Web Service Security from Microsoft:
Brokered Authentication - http://msdn.microsoft.com/en-us/library/aa480560.aspx
The main topic is - Web Service Security
Scenarios, Patterns, and Implementation Guidance for Web Services Enhancements (WSE) 3.0
http://msdn.microsoft.com/en-us/library/aa480545.aspx
Ultimately theres lots of ways you could do it. I achieved a simple single sign on by building a url with a token from one website pointing to another domain. The encoded & encrypted token contained details to submit back to the previous domain. Upon receiving an incoming request on the second domain, an underlying web service checks that the incoming request's token is valid with the previous domain using a shared private secret, known to both domains.

Resources