When we want to use OAuth with Azure API Management, the documentation states that we need to associate the APIM instance with an OAuth server in the OAuth 2 section of the portal.
But I'm a bit confused about this because when I missed doing that, the validation of a JWT token (Validate JWT policy) works just fine.
It sounds like the association between APIM and an OAuth 2 server is only needed when we want to use OAuth 2 from the developer portal or the developer console.
Am I right?
OAuth server registration is done only for the purpose of including OAuth security definition into exported spec and so that test console on dev portal will render convenient UI to obtain tokens to make runtime calls. It's not required for validate-jwt policy.
Related
I have created a Web API using .net core 5. I have secured the app using the Microsoft Identity platform. Clients app are able to get to the resource based on their scope/role. So I know that my api is secure.
Now, I need to add the API to Azure API Management tool.
So my question is should I enable OAuth from the Azure API Management to secure my web api even though my app is already secured?. What would be the reason that I enable OAuth from API management?
APIM is a proxy to the backend APIs and implementing security mechanisms to give an extra layer of security to prevent unauthorized access to APIs is a recommended practice.
Configuring OAuth 2.0 Server in APIM merely enables the Developer Portal’s test console as APIM’s client to acquire a token from Azure Active Directory. In the real world, customer will have a different client app that will need to be configured in AAD to get a valid OAuth token that APIM can validate.
OAuth is an authorization framework which allows a recognized client to acquire an access token from an authorization server.
As given in this Microsoft Doc, the Microsoft Identity Platform uses the OAuth 2.0 protocol for handling authorization.
Please find below references makes you how OAuth secures the Web APIs/Services:
OAuth 2.0 and Azure API Management
How does OAuth secure Rest API calls
Protect APIs using OAuth 2.0 in APIM
I'm currently trying to implement the OAuth 2.0 authorization code grant on a public client/native client (Android App).
Since it is impossible to store the client_secret on the device, I wanted to use this grant type with rfc7636 / Proof Key for Code Exchange by OAuth Public Clients (PKCE).
I'm using wso2 5.3.0 IAM in the backend.
The Authorization step works perfectly fine, but I'm not able to get the Access Token without a client_secret: invalid_request, Missing parameters: client_secret
Did I misunderstand the authorization code grant with PKCE wrong or did I miss some configuration in the IAM?
In comparison: It is possible with auth0.
Best Regards,
Robert
Even if you use the authorization code flow, client_secret is required at the token endpoint if the client type of your application is confidential. "4.1.3. Access Token Request" in RFC 6749 says as follows:
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.
So, change the client type of your application to public. I don't know WSO2, but I guess that it provides settings menu to switch the client type like below.
(screenshot of Authlete's web console)
The definitions of confidential clients and public clients are described in "2.1. Client Types" in RFC 6749.
Yes, the client_secret is mandatory in WSO2 IS implementation due to the Apache OLTU library that has been used internally to implement the OAuth2 feature.
Currently there is no way to register an application as a public client as explained.
However that doesn't mean there are necessarily any security pitfalls. Basically what the recommendation says is, not to embed the client_secret in a mobile app, because it makes it vulnerable. It doesn't provide any additional security for protected backend resources, because the client request is anyway not authenticated using client_secret. If you just treat the "Base64(client_id:client_secret)" as one single string it doesn't make any difference in the protocol or security of the protocol.
So when using WSO2 IS with mobile applications, following recommendations need to be followed.
Use authorization code grant type, which requires the client_secret.
Use PKCE (after WSO2 IS 5.2.0)
If you have other type of clients or channels for the same applications, e.g. like web, then register them as a separate service provider in IS and generate a separate pair of client_id, client_secret for them.
Disable "client_credentials" grant type for the particular OAuth2 mobile client you register in WSO2 IS, so that those apps can't get an access token without user authentication.
Going one step further, if you need to have unique client credentials for each instance of the mobile applications then use OAuth2 Dynamic Client Registration (DCR) to generate client credentials on the fly.
By following above 5 recommendations, it gives you the same level of security as recommended in the specification.
For Authorization grant flow you can send the request with empty client_secret. Try putting empty string like this client_secret='' and it should work as expected. You cannot request TOKEN_URI without client_secret parameter.
PKCE is used to protect theft of authorization code, Authorization code is valid for 10 minutes, when auth code is redeemed for access_token we also send code_verifier to make sure the auth code is not stoled by someone. code_verifier and code_challenge are generated together and code_challenge is used while requesting for auth code & code_verifier is used while requesting for access_token
By reading Cognito Identity Provider document, I understand that it looks like it provides out-of-box integration with Facebook / Google / Twitter as Identity Providers.
My application is a developer focused application so I would like enable users sign-up/sign-in with their Github account besides the above Identity Provider's accounts. Is that possible?
If possible, how much extra work (comparing the out-of-box Facebook/Google social sign-up feature) I need to do?
Since first writing this answer, I implemented and published a project that provides a wrapper for Cognito to talk to GitHub. It comes with a SAM/cloudformation deploy script, so you can create a CloudFormation stack that provides the wrapper very easily.
So, OpenID Connect is built on top of OAuth2.0. It's an extension - in OpenID Connect, the OAuth endpoints are there (with one or two extensions or changes), plus some new endpoints.
My understanding from reading the Cognito documentation and the relevant bits of the OpenID Connect and OAuth2.0 specs is that Cognito only uses four of the OpenID endpoints - Authorization, token, userinfo and jwks. You can specify each endpoint separately when configuring an OpenID Connect provider in Cognito. This means it is possible to provide OpenID Connect for github by implementing these endpoints.
Here's a rough plan for implementation:
Authorization: In the spec, this looks to be the same as the OAuth2.0 endpoint (plus some additional parameters that I don't think are relevant to using github as an identity provider). I think you could:
Use the github Auth URL: https://github.com/login/oauth/authorize
Set your GitHub OAuth app to redirect to https://<your_cognito_domain>/oauth2/idpresponse
For the other endpoints, you'll have to roll them yourselves:
Token: This is used to get the access and ID tokens - using a code returned by the authorization callback. It looks the same as the OAuth2.0 endpoint, but also returns an idToken. It looks possible to make an implementation that passes through the code to github's token endpoint (https://github.com/login/oauth/access_token) to get the accessToken, and then generates an idToken, signed with your own private key.
UserInfo: This doesn't exist at all in OAuth2.0, but I think that much of the contents could be filled in with requests to the /user github endpoints (since at this point the request contains the authenticated access_token). Incidentally, this is the reason that there's no open source shim to wrap OAuth2.0 with OpenID connect - OpenID connect's primary contribution is a standardised way of communicating user data - and since OAuth doesn't have a standardised way to do this, we have to write a custom one specific to GitHub (or any other OAuth-only provider we wanted to use for federation).
JWKS: This is the JSON Web Key Set document containing the public key(s) that can be used to verify the tokens generated by the token endpoint. It could be a flat file.
I have implemented the above, and the approach works. I open-sourced the project here.
Unfortunately it's not possible. Cognito Federated Identities can support any OIDC Identity Provider but OAuth2.0 spec does not give that flexibility, so there's no easy way to achieve this unless we add special support for Github.
I've been trying to learn some server side frameworks these days. I am not an expert of oauth2, but I had use an api with a team. They gave me an access using Resource owner credentials grant, with a grant_type as password, client_id and client_secret. I can log in on multiple browsers at the same time. As I have tried sails js oauth 2 and laravel passport oauth2. I got confused. Both of them using grant_type password revoke my old access_token. Using laravel passport and sails js oauth2 with grant_type password. I can log in only on one device or browser at a time. I'm confused which one is the right thing to do.
Is this how oauth2 really works? you can only log in and use one access token?
If this is the standard way, revoking the old access token. What type of grant type should I use. so my multiple devices can log in at the same time?
The behavior --- whether issuing a new access token invalidates existing access tokens or not --- depends on OAuth 2.0 server implementations. The OAuth 2.0 specification (RFC 6749) does not impose any restrictions on the behavior.
In fact, a certain OAuth 2.0 server implementation provides a feature to enable server administrators to configure the behavior. The following is a screenshot of the description about the configuration item ("Single Access Token Per Subject").
So, what matters is not grant_type but the implementation policy of the OAuth 2.0 server you are using.
I am new to security domain, so don't know whether this question is valid to be asked here. I am currently using OpenAM for the security of my web application with J2ee agent, now I find that OpenAM can do authorization with OAUTH as well as on the basis policies defined, now both openam and oauth develops tokens for valid users, and do not share user credential with the application, so how different are the two? My second question is if my application does not support oauth like google and facebook what basic things I need to do to implement oauth into my application.
OpenAM supports OAuth based authorization if that is what your confusion is about. It also supports
1) OpenID Connect
2) SAML
Your application can use either of these to get authorization from OpenAM. Your application can also use the REST APIs for this purpose. The choice is yours.
As far as the tokens go, OAuth tokens are different from OpenAM Tokens. OAuth tokens include
1) refresh_token
2) access_token
The access_token is used for making oauth based calls. However, OpenAM tokens are basically what is there in the cookie or what you get via the REST API.
Regarding your second question, to support OAuth, you would need to use a oauth client library and enable oauth on the server side (in this case OpenAM). This client library would be dependent on the language you choose to write this application.