OAuth implict grant flow and refresh token - angularjs

For now I have Asp.Net WebAPI and client application (Angular) on separate hosts. As for authentication, WebAPI uses default external OAuth provider (Google) implementation with middlewares, external bearer token and cookie. Since web application is being hosted separately, for security reasons it is using Implicit grant flow, so access_token is being returned after hash symbol in URI. Also, it means that refresh token can not be implemented.
Here comes the part I am a bit confused about.
As for my WebAPI I am using Local accounts, which have to be created for every new user that comes to my application externaly (from Google) using basic information it provides. So the external bearer token and cookie are only used till I register the user, sign him in and provide LOCAL AUTHORITY bearer token which can be used to access secured API endpoints. It means I still have the LOCAL AUTHORITY provider which lives in my WebAPI and manages access_tokens.
Does it mean that I can implement refresh token?
If I understand correctly refresh token is not valid between Google and my app (because it is using implicit grant flow), but it is viable between my WebAPI and Client application without leaving security holes?
I am a bit confused about the refresh token here. Is it possible?
Thanks for your time.
Kind of Solution
Read this answer for the solution

Related

How can I get access- and refresh-token from Azure AD B2C using a certificate?

Context
We are transitioning our Spring Boot application (with Angular frontend) from Spring's build in OAuth2 based security to Azure-AD. This is working well for clients we can update right away (mainly the B2B clients). However some (most B2C) clients can not easily be updated at the moment. In time this will happen, just not now. So I need a solution for the mean time.
Our idea
We proxy the request for the Azure tokens via the Spring Boot backend. From the client's point of view, it would look like the old solution. Username and password would be authenticated against the backend's database. Upon successful authentication, a certificate would be looked up for the user and this would be used to aquire an access and refresh token from Azure-AD B2C containg also a token for B2B.
That token would be wrapped into Spring's old OAuth2AccessToken and sent back to the client. The refresh request would be proxied in a similar way.
I have the refresh part working based on this: Web sign in with OpenID Connect in Azure Active Directory B2C -> Refresh Token
The problem
Using Microsoft's Graph API I can get an access token, but the part of the MsalToken extends AccessToken that is public (AuthenticationResult implements IAuthenticationResult) does not let me access the refresh token even if I request scope offline_access and if it is contained in the result.
Questions
Are there security concerns that make this idea a fundamentally bad idea? I'm aware that this requires trusting the backend, but that was the case so far. To me that does not seem to make it worse.
Is there a way to get an access- and refresh-token for a user be presenting the users certificate (or another none-interactive method - but we do want to use MFA as well for updated clients). I tried using Microsoft's Graph API, but a direct web-request is fine too.

Spring OAuth2 Single Page Application Integration to Azure

I have been tasked with integrating Azure Active Directory Authorization into one of our applications and have tried out some of the samples with relative success.
I have a Javascript SPA application (GoogleWebToolkit) that communicates with a Spring REST (not Boot) API. The Rest API is currently secured with Spring Security and login URL username/password etc.
I want to change this to use Azure OAuth2.
Being new to OAuth2 I'm trying to figure out if I should be using either of the following Spring options.
With this option all the configuration is done at the server side, client id,secret
If I do a href from the SPA front end to 'oauth2/authorization/AzureAD' URL, its sends a redirect to the Azure Login page, allows authentication and redirects back to what redirect URL I enter into the Azure AD console configuration. This works to a degree but trying to extract the token and pass it back is not working so far.
http.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService())
.authorizationEndpoint()
.authorizationRequestResolver(
new CustomAuthorizationRequestResolver(
clientRegistrationRepository(),
#Bean
public ClientRegistration clientRegistration() {
ClientRegistration.Builder builder = ClientRegistration.withRegistrationId("AzureAD");
builder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
........................
or
I haven't fully tried this option yet, but I think it involves doing the authorization directly from the SPA javascript front end, put all the values for the client id/secret into the javascript FE etc, and then passing the once acquired token via the Auth header for validation by the server side. Like at https://www.baeldung.com/spring-security-oauth-jwt
.oauth2ResourceServer()
.jwt()
.jwkSetUri("https://login.microsoftonline.com/common/discovery/v2.0/keys");
Could someone confirm where I should be using Option 1 or 2, and if I am understanding things properly?
Your understanding is correct in option 2. As per above scenario, let’s consider Front End Application which is Single Page Application (Java Script) to be OAuth Client App to orchestrate the process of obtaining access token and then grant access to resources from Spring back-end application.
So, here client Application need to be registered in Azure AD to acquire the access token secured by Azure AD.
We recommended MSAL libraries which helps to acquire tokens from the Microsoft identity platform and handle token in many ways to authenticate users and access secured web APIs.
Both the applications (front end and back end) need to register in Azure AD based on the scenario.
Update client-id, tenant-id, redirect URI to front end application configuration file based on application registration in Azure AD.
Back-end application also need to be registered in Azure Ad to secure by Microsoft Identity which can then define the delegated permissions(scopes) your API exposes.
Then business logic needs to add in back-end application to determine what is allowed or prohibited based on these scopes in access token.
To authorize the client request in Spring application:
Users will start by authenticating with a username and password in front end application.
Once authenticated, the client will receive a JWT representing an access token.
The client will include the access token in the authorization header of every request to a secure endpoint.
The resource server will validate the access token and determine if it has the right permissions, using the information within the token.
In this case, Spring serves as resource server and not acquiring any token in the back-end application .
Security Configuration in Spring provides numerous methods to add filters to the HTTP request to authenticate each request.
Here,
http.cors() will allows Cross-Origin Resource Sharing (CORS) checks to succeed.
All the requests need to authenticate before passing to the application(controllers).
Spring application serve as a resource server and authentication should be provided via JWT access tokens and further validate the roles and scopes in the application’s controller using #AllowedRoles annotation.
Our JWT access tokens are signed by Azure AD and application should check if their signature is correct. Azure AD has an endpoint with the public key to do so, which need to configure in spring application.
Also, as mentioned, we will need access token to call the protected back-end application because contents of the token are intended for the resource (back-end API) to perform authentication and authorization.
To validate the token, you can search the keys endpoint in the discovery document and then provide this JSON web key (JWK) endpoint straight away where JWK URI can be found.
# application.properties
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.windows.net/common/discovery/keys
Note: The flow would be same to get the access token while integrating with Azure AD. i.e in Spring boot or in spring.

React SSO using SAML without web server

I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.

Multiple AngularJS services auth token in a centralized place/ component

For multiple AngularJS services that makes it's own Web API calls, we need to store the authentication token in a centralized place and it shouldn't be repeated. Where should we save the authentication token? I guess we need to write a authentication AngularJS service that would be responsible for log-in/log-out and it stores the generated token in client local storage so this token can be sent with each request to access secure resources on the back-end API. Kindly answer me if my understanding in correct.

Where are refresh tokens generated in a JWT Authentication scheme?

I'm building a SPA with AngularJS with communication to a Laravel PHP backend. The Authentication method uses JWT, with the tymon/jwt-auth PHP library, which seems to me like a great library.
When user sends his username/password, the service sends back the JWT, which is stored in localStorage on the client. This works fine. However, I want to use a refresh token to continue issuing fresh JWTs to the client, to keep the user logged in as long as he is using the application. Where are these refresh tokens supposed to be issued? Should they be issued when a user sends his username/password? If so, there doesn't seem to be a way in the tymon/jwt-auth library to send the refresh token to the client. Please help, I'm having a lot of trouble conceptualizing how this is supposed to work.
Whether or not you get issued a refresh token when you authenticate with an OAuth 2.0 authorization server depends on which OAuth grant you're using.
When your client is a SPA (an untrusted client), you're probably using the implicit grant and that grant does not support refresh tokens.
Some companies have implemented libraries that are able to refresh access tokens issued by the authorization server using requests in a hidden IFRAME. I'm not familiar with the library you are using.
See also this question for more info.

Resources