So we've implemented Identity Server 3, and we have an app that authenticates using Resource Owner Flow. We'd like to pass additional information with the Resource Owner Token endpoint call and pass in the desired language with that call and then on successful authentication, check in the database to see if the user has updated their language settings on the device so we can pass down the correct localized strings from then on.
We basically want the database to effortlessly sync with the device's chosen language so the user doesn't get English text if their phone is set to Spanish, for example.
Is it possible to override the login method on Identity Server 3 to pass additional information? Or is there a simpler way to go about accomplishing what we want to do?
I found this: How to pass some more parameters to token endpoint web api 2 would that be the correct way to go about accomplishing this?
Related
We are implementing the integration of our existing web resource with Rocket.Chat. We are using the community version of Rocket.Chat. For this, user authorization via OAuth2 has already been done.
Now I am faced with the problem of proactively creating a user (when applying for a job, for example) without the participation of the user himself. Rocket.Chat API allows you to create a user, but it is a normal user (when creating, you cannot specify that this account will be authorized via OAuth and, accordingly, associate it with the account of the web resource).
Another option: on the side of the web resource, simulate a request for obtaining an Authorization Code via the OAuth protocol and send a correct response to this request to the Rocket.Chat server. Thus, the Rocket.Chat server would then receive the user's token and data and automatically create his account. But this is impossible, because according to the protocol specification, when requesting an Authorization Code, the client pass a randomly generated string ("state" field), which is returned unchanged when answering this request, and the server, checking the equivalence of this value, protects itself from such manipulations.
I am also trying to work with the Rocket.Chat Apps-Engine framework, but I still can't figure out how to create such accounts through it.
I would be grateful for any experience or ideas on how to solve this problem!
I'm integrating Dropbox support in my application, and to get an access token to a user's account I use their OAuth2 flow. After the user has granted the application access I need the user to be redirected to the same URL it came from. The problem is that a user may come from any of a number of subdomains, and I don't have full control over these subdomains, which means I can't add them all to the redirect URL list in my Dropbox app settings.
I thought I'd solve this by having a general redirect URL under the www subdomain, which in turn would redirect to the correct URL. However, there doesn't seem to be any way to send custom data that Dropbox will include in the redirect URL. I've expermiented with YouTube's OAuth2 API and they allow you to send custom data in a state query parameter, which it will include when redirecting back. But this does not seem to be allowed for Dropbox. Does anyone know whether there is any way to do this?
Thanks
Dropbox supports the state parameter (up to 500 bytes, see the docs for /1/oauth2/authorize), and you can set arbitrary state in the Python SDK using DropboxOAuth2Flow.start.
When you complete the OAuth flow and call DropboxOAuth2Flow.finish, the state you passed in will be returned as the third member of the tuple.
If Dropbox doesn't honor the state parameter (and violates the spec doing so) the only alternative is to make sure the custom domains redirect to the general domain as well before kicking off authentication towards Dropbox, and then store the custom URL in a cookie that resides on the same general domain as the redirect URL. You can then pickup the state/custom URL from the cookie on return from Dropbox.
I am writing an application which will connect to multiple email servers using OAuth. As part of initial connection establishment, user will be prompted to give access to application. After granting access, it will redirect to the url provided while registering the application in OAuth API.
Now i want to identify for which user the access token and refresh token belongs after redirect url comes to my application. I want to treat all requests happening in one user session as unique. Can someone help me.
I'm not 100% sure I followed your question, but my understanding is that you want to determine some of the information about the user that's just logged into your API client. You can get email addresses by requesting the https://www.googleapis.com/auth/userinfo.email scope and running a oauth2/userinfo GET request:
gapi.client.oauth2.userinfo.get().execute(function(resp,raw)...
Depending on which scopes you have access too, you will also get a display name and some other info. Best bet is just to console.log(resp) and pick out what you want to use.
Creating an angularjs single page application trying to use a RESTful API and I came across a problem that I can't seem to find an answer for. I was trying to prevent session hoping, one user logged in watching the requests figures out his account ID is 13. So he performs the same request but this time alters the request to get info for account ID 14.
So after the user logged in I was setting a session variable to his account ID and was going to strip the account ID out of the ajax requests. I then tried to access the Session from a class inheriting from ApiController. After looking around I realize that storing session information is not very RESTful.
So how would I go about ensuring that one account cannot access another account's information just because they watched the ajax requests and figured out how to manipulate the ajax request?
Is restful not meant to be used with users that need to authenticated and authorized? I was thinking of maybe hashing the IDs or something but I am not sure that is the right approach.
UPDATE:
I have token based authentication working now. But I am still in the dark as to how to prevent someone from fiddling with HTTP request and getting information that doesn't belong to him. For Example, I want to retrieve all the users for account with ID 14.
HTTP Get /users/14
I have a token so I know that the person trying to use the web API at some point authenticated themselves. I can lock it down to roles. But there is nothing stopping this authenticated person form fiddling/hacking with the request and doing the following
HTTP Get /users/58
Now the person has got all of account with ID 58's information. This is information does not belong to account 14 but now he can browse through other people's information.
I need someone of knowing that the request that comes from the browser and says it is for account with ID 14 that it really is account 14. I can put that information in the token but how do I check it in a handler or check it in the ApiController?
The problem you have described is not something unique to REST-based services. In fact, this is one of the top 10 OWASP vulnerabilities (Insecure Direct Object References). You will need to first identify the user and then authenticate the user. For identification, an ID is used, such as user ID. The identifier can be anything you want. After identification, you need to authenticate the user. This is done by authenticating the credential presented to the app, such as password. The identifier and the credential can be any thing, say the good old user name/password, or may be a token or may be an API key. It actually does not matter to the problem on hand. Once authenticated, you authorize the requests based on what the user can do in your app. The authz part is a must regardless of whether you use a token, certificate or what not. Hashing user ID or using some method to hide things is security by obscurity and is not a good practice.
Say, you are using a message handler to authenticate the credential submitted by a user. Once authentication is done you can store the account number associated with the authenticated user in the properties collection of HttpRequestMessage. This is done in the server side and no user can make the system store some random account number. Only the account number associated with the authenticated user is stored in the properties collection. With that, you can now authorize requests. Say, you can write an authorization filter that pulls this account number and compare it against the account number in the URI to determine if the request is allowed or not. By applying this filter against a GET action method, you can ensure only right folks can see right data.
For example, a user with user ID 'abc' and password 'pwd1' makes a GET request to /users/14. First step is, you will authenticate the user ID. If there is a user with ID 'abc' and password 'pwd1' in your store, you will consider the user authentic. As part of this authentication, you can pull the account number associated with the user 'abc'. Say it is 15. You will store 15 in request.properties. From your authorization filter, you can get the account number from URI, which is 14 and compare it against the one in the request, which is 15. Obviously the numbers do not match and you reject the request in the OnActionExecuting method of your filter with a 401.
What I described above is a simple approach. Better one (in terms of extensibility) will be to use claims but it will not be possible to explain all that here. You can get good amount of information related to claims-based identity from Dominick's blog.
Every request should be authenticated. If the credentials provided do not allow the user with account 13 to access data from account 14 then the request will be denied. The trick is to find a way to do authZ quickly.
You seem to be missing the information on how you want to implement authentication. As you correctly noted, using session to keep authentication information is not very restful. Here are the alternatives
Implement your own OAuth provider or use third party (for example
Azure ACS)
Implement STS provider (this is only for soap though)
Implement a custom token system, if you don't want to deal with
the above two. Basic system would take user id, salt it and encrypt with private key - but don't quote me on how secure that would be...
In all the cases, the authentication information is stored in the cookie, similar to session cookie. But it is still stateless.
The standard way on the web seems to be the oauth way, in fact the standard VS MVC template even comes with OAuth consumer implemented out of the box. So the question is, how do you link the oauth token to your internal user ID. That's really pretty simple, as you implement the "registration" step after the new user is authenticated - you keep user ID and oauth token in the database table, to link the two.
That link is quick to retrieve, and can be cached for speed. I have heard some people implement that type of credentials caching for some very big systems (google docs).
I have a json API for some resources owned by users. I have protected API access using an API access key as described in this railscast: http://railscasts.com/episodes/352-securing-an-api
This works fine, I have a unique key for each user that they have to submit when they want to add/update/delete a resource. The problem I'm having is, aside from the API, users should be able to edit the resources from a Web form. This does not work though, since the form does not submit the API key in the header and so access is denied.
Is there a way to get the form to send the access key for the user since they are logged in already? Or perhaps I am going about it wrong? Perhaps I should check if there is a active session and in that case use that as authentication instead of the API Key?
Is there a way to get the form to send the access key for the user
since they are logged in already?
The API access key can be sent for the user by including it as a hidden field in the form. Once you receive it, you can compare it with the assigned access key for the logged-in user.
But think about your customers and your business. Including the API key in a clear-text within the form is like giving the hackers, literally, access to alter anything they want, especially if HTTPS is not configured.
Perhaps I should check if there is a active session and in that case use that as authentication instead of the API Key?
Yes, this is one of the secure methods to do it. The first method you mentioned is not secure at all. Don't put any thing related to authenticating in a place where it can be easily altered (form, cookie).
If you wish, you can use both session-based authentication with API access Key. How? Lets say you generate an API access key with expiry date for each modification request. Each modification is required to be submitted within x minutes after it is triggered. Once submitted, you authenticate the user against session and the modification against API. This is just an example.