Spring Security Microsoft Oauth2 Login Errors - spring

I'm attempting to access Microsoft Account oauth without any Azure AD accounts, but I am receiving an unauthorized_client error before the redirect back to my app.
Here is my yml configuration for spring security:
spring:
security:
oauth2:
client:
registration:
microsoft:
client-id: [my app registration client id]
client-secret: [my app registration secret id]
scope: profile, openid, https://graph.microsoft.com/User.Read
client-name: Microsoft
authorization-grant-type: authorization_code
provider: microsoft
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
microsoft:
authorization-uri: https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize
key-set-uri: https://login.microsoftonline.com/consumers/discovery/v2.0/keys
token-uri: https://login.microsoftonline.com/consumers/oauth2/v2.0/token
user-info-uri: https://graph.microsoft.com/oidc/userinfo
userNameAttribute: sub
issuer-uri: https://login.microsoftonline.com/${app.oauth2.tenant-id}/v2.0
app:
oauth2:
tenant-id: [my tenant id]
Client and secret ids match within both yml and azure portal. SSO fails both locally and when deployed. Is there any additional configuration I need to do here in order to get this working or do default Microsoft clients just not work whatsoever with java oauth?

There are actually several "features" in Microsoft's SSO implementation preventing OOTB functionality.
Issue 1: Token contains an extra nonce that violates the JWT specification
Resolution: Create a new scope under Expose an API. This scope can be named anything. Add this scope into your API Permissions section and update your scope property for the client registration to include the new scope.
More information on this issue can be found here: https://xsreality.medium.com/making-azure-ad-oidc-compliant-5734b70c43ff
Issue 2: Invalid scopes
Resolution: Don't include any of the graph api scopes. They currently do not work for Microsoft accounts (as of 2/16/21).
Issue 3: Invalid Issuer
Resolution: Use the issuer that Microsoft is currently exposing under their well known endpoints api for whichever api you are using.
Consumer: https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration
Common: https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
I don't believe common will currently ever work since only consumer endpoints have a tenantId and that is included in the documented issuer string (as of 2/16/21), but the api has been in flux for the consumer endpoints with several different bugs. On 2/15/21, the issuer was hardcoded to "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0" regardless of tenantId and as documented in the above linked article, it was "https://sts.windows.net/407b9272-20f5-421c-a25f-e7a189309c4b/" as of 8/21/19. Currently (2/16/21), the issuer correctly includes the tenantId.
*** Update 2/18/21: despite the well-known endpoint saying the issuer accepts a tenant id, the issuer is still hard-coded to that tenantId I posted above.
Resulting YAML:
spring:
security:
oauth2:
client:
registration:
microsoft:
client-id: [my app registration client id]
client-secret: [my app registration secret id]
scope: profile, openid, [my custom scope with the full api prefix]
client-name: Microsoft
authorization-grant-type: authorization_code
provider: microsoft
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
microsoft:
authorization-uri: https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize
key-set-uri: https://login.microsoftonline.com/consumers/discovery/v2.0/keys
token-uri: https://login.microsoftonline.com/consumers/oauth2/v2.0/token
user-info-uri: https://graph.microsoft.com/oidc/userinfo
userNameAttribute: sub
issuer-uri: https://login.microsoftonline.com/${app.oauth2.tenant-id}/v2.0
app:
oauth2:
tenant-id: [my tenant id]
For the value [my custom scope with the full api prefix], make sure to copy the full scope name including the api://[app id].

Related

springboot oauth2 client azure active directory b2c issuer-uri problem

i set up spring boot with oauth2 client and here is my properties:
spring:
security:
oauth2:
client:
registration:
azuread:
authorization-grant-type: authorization_code
client-id: 'client id'
client-secret: 'secret'
provider: azuread
scope: openid
client-name: demo
user-flows:
sign-up-or-sign-in: <policy name>
provider:
azuread:
issuer-uri: https://{clientId}.b2clogin.com/{clientId}.onmicrosoft.com/<policy-name>/v2.0/.well-known/openid-configuration
when spring start up it complains:
"The Issuer provided in the configuration metadata did not match the requested issuer"
i checked implementation and found that azure b2c issuer-uri does not have policy or userflow in issuer-uri but we have to set policy name in spring configuration as path variable and after spring rest call to https://{clientId}.b2clogin.com/{clientId}.onmicrosoft.com//v2.0/.well-known/openid-configuration , spring will check response to compare it with auzre response in which they are not the same
expected:
https://{clientId}.b2clogin.com/{clientId}.onmicrosoft.com//v2.0/
result:
https://{clientId}.b2clogin.com/{clientId}.onmicrosoft.com/v2.0/
tried spring boot oauth2 reference
check azure b2c AD doc and spring sample , but i don't want to use spring boot azure AD b2c starter, only using oauth2 client
The error you are getting is due to incorrect metadata.The metadata should have tenantId rather than clientId.
It should be https://{tenantId}.b2clogin.com/{tenantId}.onmicrosoft.com/{policy-name}/v2.0/.well-known/openid-configuration where tenantId is the name of your Azure Active Directory Tenant.

OAuth2 Resource Server calling Authorization Server to validate token

I am new to OAuth2 concept but trying to setup a simple system that will consist of 2 separate microservices (no UI yet, will use REST client for test purpose):
Authorization Server with own database which will own User entity, credentials, all other information needed for MFA for example.
Resource Server with its own database, which will have a User Projection entity. I want my Resource server to drive UserManagement flow, which will save on its side non-auth user information, like address, titles, logos etc and will just call Auth Server to store auth information.
If I understood the oauth2 flow propertly i will have to:
call Authorization Server first with user/password to obtain access token.
Then using this access token i will call my Resource server.
Resource server should call Authorization Server to validate the token.
My question replies to step-3.
What I did is some basic configuration on Authorization Server side:
security:
oauth2:
client:
client-id: clientId
client-secret: very-strong-secret
provider:
issuer-uri: http://localhost:8080/oauth/token
And on Resource server side:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/oauth/token
my resource server is starting on port 8081 and calling localhost on port 8080 where authorization server is running.
I was able to obtain access token, but when I am calling resource server (I assume spring makes a magic and calling auth server under the hood) i get the error:
Unable to resolve the Configuration with the provided Issuer of "http://localhost:8080/oauth/token"
How exactly should I instruct my resource server to validate the token?
It's quite simple. If you don't configure the issuer uri explicitly, the default value is host:port.( In your case it's just http://localhost:8080 )

OAuth2.0 Spring Security

I have a question regarding the oauth2.0 openId and spring boot. I am developing a personal project, and I have deployed a Keycloak instance as an Auth server and I am writing code for the resource server. I would like to ask you some questions regarding security. As the Spring Docs say, we need only the issuer-uri of the Auth Server and the Resource Server will use this property to further self-configure, discover the authorization server’s public keys, and subsequently validate incoming JWTs. For example a resource server will have to specify the following:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: <uri>
However, this means that any resource server can use my deployed Auth Server to self configure just by knowing the issuer-uri is there any way to protect the Auth Server from resource server APIs(that are external to my application)?
Thank you in advance!

Why Authorization Endpoint of WSO2 identity server always redirect to 127.0.0.1:9443 even if it is behind a http proxy

I write a spring security app which uses WSO2 identity server (ver. 5.7) as oauth2 server. The application.yaml file is just as the follows:
spring:
security:
oauth2:
client:
registration:
wso2is:
client-id: <id>
client-secret: <secret>
authorization-grant-type: authorization_code
redirect-uri-template: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: openid
client-authentication-method: basic
client-name: WSO2 ID Provider
client-alias: wso2is
provider:
wso2is:
authorization-uri: https://<mydomain>/oauth2/authorize
token-uri: https://<mydomain>/oauth2/token
user-info-uri: https://<mydomain>/oauth2/userinfo?schema=openid
user-name-attribute: sub
jwk-set-uri: https://<mydomain>/oauth2/oauth2/jwks
client-name: wso2is
And in the identity server, I add a new service provider and add an Oauth/OpenID Connect Configuration under Inbound Authentication Configuration, the Callback Url of which is set to be http://localhost:8080/login/oauth2/code/wso2is.
The identity server itself is behind a http proxy of nginx, and I can log in the admin console using https://. I've also changed both HostName and MgtHostName to .
The question is when I access the spring security app via http://localhost:8080, it is redirected to a url of https://127.0.0.1:9443/authenticationendpoint/login.do?client_id=xxxxxxx, and from the log, I find it says Redirecting to 'https://<mydomain>/oauth2/authorize?response_type=code&client_id=xxxxxx. If I access the url directly, it is actually redirected to the https://localhost:9443.....
All the samples in the docs are all demonstrated in local environment, but how can I handle my case please?
Open <IS_HOME>/repository/conf/tomcat/catalina-server.xml file and add the proxy port 443 in https connector as follows.
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="9443"
proxyPort="443"
There are some additional steps [1] when configuring a proxy server for WSO2 IS if you need to work with the end-user dashboard as well (<IS_HOST>/dasboard).
[1] https://docs.wso2.com/display/IS570/Setting+Up+Deployment+Pattern+1#SettingUpDeploymentPattern1-ConfiguretheProxyPortinISNodes

JHipster with OpenIDConnect Authentication

Do you have any example configuration for OpenIDConnect (Microsoft ADFS) configurations for JHipster generated application?
OKTA configuration is working fine, but pointing to Microsoft ADFS config is failing.
My Config:
security:
basic:
enabled: false
oauth2:
client:
access-token-uri: https://<domain.com>/adfs/oauth2/token
user-authorization-uri: https://<domain.com>/adfs/oauth2/authorize
client-id: sada-sdasd-asds-adas
client-secret: jhasdsadsasadasdsadsa
client-authentication-scheme: form
scope: openid profile email
resource:
user-info-uri: https://<domain.com>/adfs/userinfo
prefer-token-info: false
I am currently working on this also. I get to the login screen but then have some problems when redirecting back to the JHipster app.
The steps you need to have (which I've also done and are working up to ...) are:
Create a new application in the azure portal as described in registration here: https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-openid-connect-code
In order to get the links you need, you need the tenant ID, which you can get following these steps: https://techcommunity.microsoft.com/t5/Office-365/How-do-you-find-the-tenant-ID/td-p/89018
The authorize, token and userinfo links you get based on tenant id like this: https://login.microsoftonline.com/{your-tenant-id}/.well-known/openid-configuration
Hope it helps!

Resources