MVC5 allow relying party to use JWT security tokens - asp.net-mvc

I am using Thinktecture IdentityServer v2, the Relying Party token type is set to none. The code runs fine with this setting.
I am looking to use JWT tokens so I have a common interface from my MVC app to the API, and also from phone/tab app clients to the API.
When I set the token type to JWT, I sign in on IdentityServer then it throws the following error:
ID4014: A SecurityTokenHandler is not registered to read security token ('BinarySecurityToken', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd').
I created a standard MVC app and had set the Authentication to Organizational Accounts -> On premise, and had set On-Premises Authority to the IdentityServer metadata url.
I plan to call WCF from the MVC app (and perhaps even javascript code on other platforms).
So far I have installed the specific JWT handler Update-Package System.IdentityModel.Tokens.Jwt -Version 3.0.2 (v4.0.0 has an issue apparently with Thinktecture IdentityServer v2) and then set the web.config to include:
However I then get a new exception when logging in:
Jwt10315: Signature validation failed. Keys tried: 'No non-null SecurityKeys were found'.
jwt: '{"typ":"JWT","alg":"RS256","x5t":"_rKoogN25ibGWZGC94xaed9g7FE"}.{"iss":"http://identityserver.v2.thinktecture.com/test","aud":"https://localhost:44302/","nbf":1419269158,"exp":1419305158,"nameid":"user","unique_name":"user","authmethod":"http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password","auth_time":"2014-12-22T17:21:43.655Z"}'
How can I have the MVC app so it can consume JWT tokens?

Why do you want to use JWT? Especially when you want to call WCF at some later point - JWT is the wrong choice. WCF works best with SAML tokens.

Related

Azure B2C authentication with Implicit Grant Flow

I'm using an Azure B2C Tenant which has some users. I created an application and in the authentication I choose web. I deselected the implicit grant flow because I was getting the warning This app has implicit grant settings enabled. If you are using any of these URIs in a SPA with MSAL.js 2.0, you should migrate URIs. I selected Local only and no other provider. I also have a Sing In User flow. I could not even see the login page from my C# ASP.NET application with those settings. So I selected the implicit flow. That solved the problem and I can see the login page and can login.
My question is why should I need am implicit flow for a web authentication.
If you're using the Microsoft Identity Web authentication library or one of the Microsoft Identity Web project templates, then it passes response_type=code id_token in the authorization request, which represents the hybrid flow.
This is why you must select the "ID tokens" settings for the application registration.
You don't need implicit flow unless you are using older versions of MSAL i.e., MSAL1.XXX version.
The latest version of MSAL.js i.e., MSAL 2.XXX version only works with
the authorization code flow with PKCE instead of implicit flow . So
you need to implement PKCE flow instead of implicit Grand.
If you are using latest version of MSAL please don't use Access_token and id_token settings which will enable implicit flow.

Using JWT to authorize REST API requests after SAML Authentication

I'm struggling theese days on the possible way to configure an Authentication + authorization system to consume a REST API from a mobile application.
Scenario:
We've developed 3 independent portals for a big customer that serves several users.
To enable a SSO for the 3 portals we've implemented a SAML authentication system using SimpleSAMLphp.
Every portal has a service provider and they make assertion requests against a central IdP.
The IdP checks username and password against a database where passwords are hashed and stored during registration.
After the login, the authorization on the portals is handled by the session on the server, and so far everything was fine.
Now the customer asked us to develop a mobile application that will require the users to login and access several of their protected resources collected during the usage of the 3 portals.
We've decided to develop a frontend application using ionic that will consume a REST API made in node.js that will serve all the data (both protected and unprotected resources).
Now here comes the question: to authorize access to protected resources on the Api we'd like to use JWT to easily achieve a stateless system.
The doubt is how to perform the authentication? We've the opportunity to check the credentials directly against the database skipping the SAML process, otherwise we've to implement a solution where the SSO IdP acts as authentication provider and then when an attempt is successful the API app will get the response from the idp and then issue a signed jwt to the consumer client. Is this second way a common implementation? Is it possible?
What path do you suggest to follow? The first could be very easy to achieve, but since we're using html+js for the app's frontend, if we decide to use the second solution probably in the near future we could recycle some code from the app to modernize some functions on the web portals, maintaining the jwt pattern and consuming the new Api also on the web.
I believe that in this case will be easier to ask a token to the new api using someway the logged in user's data already in the session of the portal. Sounds possible?
I hope that everything was clear, any help will be appreciated!
Thanks
The key goal here is to code your apps in the best way, via
the latest security standards (OAuth 2.0 and Open Id Connect).
SAML is an outdated protocol that is not web / mobile / API friendly, and does not fit with modern coding models.
Sounds like you want to do OAuth but you do not have an OAuth Authorization Server, which is a key part of the solution. If you could migrate to one you would have the best future options for your apps.
OPTION 1
Use the most standard and simple option - but users have to login with a new login screen + credentials:
Mobile or Web UI uses Authorization Flow (PKCE) and redirects to an Authorization Server to sign the user in
Mobile or Web UI receives an access token after login that can be sent to the API
Access token format is most commonly a JWT that the API can validate and identify the user from
The API is not involved in the login or token issuing processes
OPTION 2
Extend option 1 to federate to your SAML Identity Provider - enables users to login in the existing way:
The Authorization Server is configured to trust your SAML based identity provider and to redirect to it during logins
The SAML idp presents a login screen and then posts a SAML token to the Authorization Server
The Authorization Server issues OAuth based tokens based on the SAML token details
OPTION 3
Use a bridging solution (not really recommended but sometimes worth considering if you have no proper authorization server - at least it gets your apps using OAuth tokens):
Mobile or Web UI uses Resource Owner Password Grant and sends credentials to a new OAuth endpoint that you develop
OAuth endpoint provides a /oauth/token endpoint to receive the request
OAuth endpoint checks the credentials against the database - or translates to a SAML request that is forwarded to the IDP
OAuth endpoint does its own issuing of JWT access tokens via a third party library (if credentials are valid)
Web or Mobile UI sends JWT access token to API
API validates received JWT access token

Authentication with JWT: Securing Views from the consuming client perspective

I have created a Web API using ASP.NET Core 2.1 and it uses (successfully) JWT as a method of authorising requests.
The API is linked to a SQL Server database.
My users are stored in it using Identity as the base framework.
To authorise access for my API I take the username and password which is checked against the stored (Identity based) user.
Successful login returns an Access Token (with a 30min life).
Upon first logging in, a Refresh Token is generated and stored against the Identity user and sent back from the API.
All of this works well. My next step was to create a separate .NET Core 2.1 MVC site which consumes the API.
My question is:
From the MVC site point of view, how do I secure my controllers and views based on this security set up? I would normally use the [Authorize] attribute as part of Identity.
All I have on the MVC site side at the moment is the Access Token (and Refresh token) for the user in question.
I'm thinking the following solution:
MVC Site has it's own database and authentication for users (using Identity).
The connection (credentials/tokens) to the API is stored separately in the MVC site database and used as a 'global' way on the server-side to execute calls against the API
You should use an OpenID Connect and OAuth 2.0 framework. please check IdentityServer4. It also support asp.net core identity
IdentityServer is an OpenID Connect provider - it implements the
OpenID Connect and OAuth 2.0 protocols.
Different literature uses different terms for the same role - you
probably also find security token service, identity provider,
authorization server, IP-STS and more.
But they are in a nutshell all the same: a piece of software that
issues security tokens to clients.
IdentityServer has a number of jobs and features - including:
protect your resources
authenticate users using a local account store or via an external identity provider
provide session management and single sign-on
manage and authenticate clients
issue identity and access tokens to clients
validate tokens

ASP .NET MVC - How to use token from OAuth Sign In with future REST calls

I have an ASP .NET MVC application (default template).
I have added a Nuget package for OAuth support for an external provider.
I have successfully logged in with the external provider, however I now need to use the token that they provide to make REST calls with another API I am using.
How do I get the token the external provider has given?
You should refer to the external provider's docs to see how you can get the token. For the ASP.NET's own identity you call %appurl%/token and then store it somewhere like in your session and then send it in your authorization header as described here.
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
For most providers it should work because ASP.NET itself works with the token of let's say facebook and generates a token for you itself so you always use yourapplication/token to get the token.
See this question
MVC 5 Web API with Facebook access token to RegisterExternal without need of Cookie

Javascript App with OAuth2 Authorization Code Flow?

You can implement the "Authorization Code Flow" in this situation?
A single page app in www.app.com
A REST backend in www.backend.com
Is possible to obtain via javascript an "authorization code" and then pass it to the "backend" for this get the "access token"?
In theory, using the authorization code flow (or the hybrid flow) with a JS/mobile/desktop application is definitely possible, and you don't even need to store client credentials for that (you could, of course, but extracting them is so easy that it would be pointless).
Contrary to popular belief, client authentication is not required for "public" applications (i.e apps that cannot safely store their credentials, which includes JS apps) when using the authorization code flow:
If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3
f the Client is a Confidential Client, then it MUST authenticate to the Token Endpoint using the authentication method registered for its client_id, as described in Section 9.
http://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
In practice, I'm pretty sure most authorization/authentication servers will enforce client authentication when using the authorization code flow and will instead recommend using the implicit flow for public apps.
If your authorization server supports this scenario, using the authorization code flow in your JS app should be easy if you use response_mode=query (or better: response_mode=fragment as suggested by #Hans), since you can use your JS main page as the redirect_uri and use some JS to extract the authorization code from the query string or from the fragment.
That is possible by setting the redirect_uri to somewhere in your SPA, pickup the code from the authorization response (using any of the methods described in How to get the value from the GET parameters?) and pass it on to the backend in an application specific way. When using OpenID Connect there's the option to have the code delivered in the fragment of the redirect_uri which has some security advantages over having it delivered as a query parameter.

Resources