I'm working on a project to setup oauth2 authorization. I already have brief knowledge on authentication process for spring security, but here when i setup oauth, i'm wondering how to do the authentication part? as here i both need to authenticate the clients credentials and also the user credentials( user authenticate will be do by LDAP), as the grant type would be 'password'. and after authentication, the final authenticated authentication object would be the user with his/her authorities, instead of the client.
If you either use Resource Owner Credentials or whatever other grant type that could potentially take client(program) credential and user's credential when issuing a access token, then Authentication instance you are going to get from AuthenticationManager#authenticate() will be OAuth2Authentication. And inside of OAuth2Authentication, you'll able to see another Authentication which includes user's authentication information.
With that OAuth2Authentication, you can either manaully add logic to check different stuff you'd like to by accessing OAuth2Authentication itself by getting it from SecurityContextHolder.getContext()and then typecasting to OAuth2Authenticaiton, or simply use existing PreAuthorized annotation with SpringEL.
Related
In short: How can I manually authenticate a users with a given access token?
The long story:
An Amazon Alexa Skill should access user data within a Symfony 3.4 based web services.
The web services uses FOSOAuthServerBundle to handle the OAauth authentication and link the users Alexa account to the web services user account.
Once the account is linked Alexa API includes the OAuth Access Token in every request. However, the token is not included in the request header but simply within the JSON content. Additionally all request, both linked/authorized and not-linked/unauthorized call the same endpoint / route.
Thus using the Symfony firewall to authenticate the user does not work, does it?
Instead I manually check wether the Alexa request contains an access token to provide the correct response.
If the request contains an access token I would need to manually check and authenticate the user. How can this be done?
In the OAuth authentication flow, if permission is granted by the service provider, the authorization redirects to a app-specified redirect URL with the access token (e.g. yourapp.com/redirect/?token=deadbeef).
Now the app has to store that token in some way – either directly store it in the database or start a session with the service provider. Doesn't this contradict the "laws" of HTTP methods, specifically that GET is supposed to be a read-only action?
So I'm trying to access my own data from an external app via their API. I only need access to my own data. Not trying to receive data from any of my users' accounts, so they don't need to authorize anything. So obviously I need to avoid any redirects (which seems to be the standard process the more I research OAuth...)
The process is hit the /authorize endpoint, which returns a code. Then provide that code in a request to the /token endpoint. Which then allows me to access my account via the API. I'm 95% sure this process is standard for all OAuth, but figured I'd provide details in case it's not.
How do I provide credentials on the back end to get a code to enter into the request for a token, so that all user interaction is negated? The API I'm using forces me to use OAuth.
The oauth2 grant you are describing is called Authorization Code Grant. This way of authentication has been designed so that applications which want to access resources of a user do not have access to the users credentials.
So if you found a way to interact with the user credentials in this grant it would be considered a hack.
If you do not want the individual user to enter the username and password but you want to access the api with a kind of "system account" this is not the oauth grant you should use.
There are multiple grants that would work for you. The question is which are supported by the authorization server and available to you.
Resource Owner Password Credentials Grant
This grant type is suitable for clients capable of obtaining the resource owner's credentials.
However
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged application.
It is very likely that this grant type is not avaiable as it could be misused to steal user credentials.
Client credential grant
The client can request an access token using only its client credentials.
How the resources are tied to a client is not part of the oauth specification and therefore provider specific.
If you want to read more about oauth2 here is a good article.
The Oauth 2 grant flow that you're describing is the Authorization Code Grant Flow, like NtFreX's answer says. And like they say, if you have the option of using one of the above two grants with that API, that's the easiest solution.
However, if you don't, there's still a way to avoid "user interaction". It's unclear what you mean by "user interaction", but in the Authorization Code flow, that usually means logging into a web app that calls the API you are trying to authenticate into, and then consenting on the consent page. See https://dev.fitbit.com/docs/oauth2/#authorization-page for an example (I implemented OAuth 2 for Fitbit :)). You'll need to use an automated web browser like Selenium to click the consent button. Then you can capture the code in the response from /authorize and send the code to the access token endpoint.
I am using symfony2.7 and I would like to authenticate my users whether by form login or by token in the url request. I am able to do both separately but how could I configure my firewall to be able to listen for both authentication methods whether user logs in by form or by token.
I recommend using a Guard. With a Guard it doesn't matter which authentication method you choose.
I am using the standard ASP.net OWIN OAuth middleware system to authenticate local users with Bearer tokens. I was thinking of embedding roles as a claim in the token, but was wondering how I would be able to change a users role such as taking away admin privileges without them logging out. Any ideas?
It's always possible to implement some dirty solutions to support your problem, for example :
When the roles have changed then raise an even in a queue like RABBITMQ / NServiceBus (or via event).
The subscriber (website) will invalidate the cookie and regenerate a new one with new claims.
I don't see the issue with waiting for the cookie is expired.
In fact a bearer token (identity or access) has an "expires_in" property, so even if your cookie
is regenerated with new claims, the token is still valid in the provider.
Another remark your permissions can be returned by a UMA server, they shouldn't necessarily comes from your claims.
Take a look to this scenario : http://lokit.westus.cloudapp.azure.com/Documentation#third-scenario-limit-access-to-certain-website-features