What's the best way to deal with Antiforgery on methods with ValidateAntiForgeryTokenAttribute attribute while calling from a non-browser client, say WinForm?
Based on what I know, below is how anti forgery works:
A hidden input field is added to the page, e.g.
A cookie with the same name is also sent to the client
On the next request, both the cookie and the hidden input field is sent to server. Server calls AntiForgery.Validate(token, cookie) to confirm that the request is legit.
All works fine in a web app. It doesn't seem to work in WinForm. Here is what I do:
Using HttpClient, I do a get to a page containing the token.
I parse the page and grab the hidden input field. I also pick up the cookie.
I pass the cookie as is. On top of that, I add a new header __RequestVerificationToken with value from the hidden field.
I step into the server code.
The AntiForgery.Validate(xx,yy) fails with error:
The provided anti-forgery token was meant for user X, but the current user is Y.
I figured it out. It needs Forms Authentication to be done prior and pass the cookies in subsequent WebAPI calls. So here's the revised flow:
1) Load the login form using HttpWebRequest (GET)
2) Do a POST on the login form using credentials. Do supply a cookiecontainer in HttpWebRequest
3) The cookiecontainer now contains the Auth cookies and __RequestVerificationToken
4) Grab the __RequestVerificationToken from any subsequent GET or even from the output from login result
5) For the WebAPI Post call, pass the cookiecontainer as is. Also include a header __RequestVerificationToken with value from prev step.
Related
I am currently trying to design a new web-application for a rest-api service I have running. In basic I am trying to realize the login/logoff system. For authorization-management the API provides three endpoints:
/login, which takes username and password via a POST request and returns a token embedded in a json answer. This token is not a JWT, but its some arbitrary unique string. It is valid for X hours and everytime it used it is reset to be X hours valid again. The validity is check on the server in each request.
/logout, which makes the token invalid on the server.
/validate, which takes a token as json in POST request and checks if it is valid. If not it returns a 401.
Now I realized a login procedure following https://www.digitalocean.com/community/tutorials/how-to-add-login-authentication-to-react-applications . The application finally should used the react-router to provide the different pages. My problem is not how to integrate the validation of the token on each page change and if a 401 is returned, switch to the login page again.
PS: The server is written in C++ and accesses a custom database.
As Suggested By You That You Want To Integrate Validation, So You Need To Create A Component Over The Current Route Component.
It would serve as the private Route and as soon as you get a 401 Response From Your Server You Would Redirect To The Login Page By Updating the Token as empty depenedending upon the storage you are using i.e. session storage or localstorage.
This way whenever your token expires the next request responds with 401 and you are logged out.
Further I am Linking An Example Gist For Creating Private Routes And Logging Out
https://gist.github.com/EduVencovsky/f8f6c275f42f7352571c92a59309e31d
I'm currently developing an App using Microsoft LIVE 2.0 API
Currently, I’m using these URLs as my authentication endpoints:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token
However, when I sent the request to the token endpoint with the redirect URL as
https://blabla.com/accept_token.php?api_ver=wave5&csrf=AY7F6O4hF0n8yW3i2O_y6N-ky7zzfULiYV_fttLK1S3JgaeQz2GTk9FOeIGBBH5CvkfkEYCyPOCQCujcrij4KDy2wAMZyXqx24jvwZRtzOv0s9ADGYl1iFtvYtkmgeFmZEY&appdata=%7B%22use_case%22%3A1%2C%22type%22%3A1%2C%22flow%22%3A2%2C%22domain_id%22%3A12%2C%22tracked_params%22%3A%22%5B%5D%22%7D
I got errors saying the reply address does not match the reply addresses configured for the application
For the application, I set the reply address to be https://blabla.com/accept_token.php.
Is it possible that I add some parameters to the url and still make it match?
I'm pretty sure the reply url you send must match exactly the reply url registered on the application, including any query strings.
If there is variable state informaiton you need passed throughout the authentication process, you should use the state variable.
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-code
state
A value included in the request that will also be returned in the token response. It can be a string of any content that you wish. A randomly generated unique value is typically used for preventing cross-site request forgery attacks. The state is also used to encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.
I am using OAuth 2.0 for my AngularJS application. When the user clicks on one of other application I am redirecting to my Angular application with parameters like this:
https://stic-scm-auto.snitco.com/fsHardSoft/createCase?sn=FOC0948Y1WB
When above URL is accessed I am showing them the login page. (since they are not logged in yet)
Later I am redirecting them to here :
https://cloudsso-test.snitco.com/as/
after they landed there, I am getting re-directed to login URL:
https://sso-test.snitco.com/autho/forms/CDClogin.html
once the login succeeds, it's redirecting back to the OAuth callback page of my application.
How can I pass the createCase?sn=FOC0948Y1WB - parameter to all above gateways and get the data back?
You can achieve this by relying on OAuth 2.0 state parameter. In an OAuth 2.0 compliant server the value you send in this parameter we'll be returned to you after the process completes and the authorization server redirects back to your application.
The primary use case of this parameter is to prevent XSRF by linking an original request to the redirect request so that the client application is sure that the redirect was not caused by an attacker.
However, it's also possible to use this parameter to achieve per-request customization which in your case would be knowing the original case number. See Using the State Parameter for more information about this. Just be sure that the value passed in the state should still have a random component that can later be checked to prevent XSRF; your required custom data should be in addition to this nonce value.
I am using token based security in my web app. The server side is wrote using c# and i am using openiddict for logging in and issuing tokens, found here. I am currencyly using Implict flow.
By default my tokens have a lifespan of 1 hour, after that you have to logging again. I have locked down my API to accept bearer tokens only and not cookies.
I wanted to implement refresh tokens but after reading many websites, it appears that implementing refresh tokens on a web app, is not a good way to go due to a hacker getting the refresh token. I know that to use refresh tokens, you must use code flow, instead of implict, which i can do.
How do people get round this situation in their web apps? I cant be the only one who wants a token to last longer than an hour in a web app?
The approach recommended by OpenID Connect is to send an authorization request in a hidden frame with the same parameters as the ones you use for the initial implicit flow request plus prompt=none and optionally, an id_token_hint corresponding to the id_token you extracted from the authorization response.
When using prompt=none, the identity provider won't display any consent form and will directly redirect the user agent to the redirect_uri you specify, with the new token appended to the URI fragment, just like for a classic implicit flow request. You can retrieve it by extracting it from the popup.location.hash property.
If the request cannot be processed (invalid request, unauthenticated user, invalid id_token_hint, consent required, etc.), an error is returned and the identity provider either redirects the user agent to the redirect_uri with an error parameter or stops processing the request.
Note that due to the same origin policy, you can't access popup.location.hash if the current location belongs to a different domain (e.g if the identity provider refuses to redirect the user agent to your client app): it will throw an access denied exception. In this case, it's always better to add a timeout to your "refresh" operation.
Sadly, there are very few libraries that can help you with this task. oidc-token-manager is one of them, but it has a few limitations that will prevent it from working OTB with OpenIddict: it doesn't support raw RSA keys (you have to explicitly use a X509 certificate in the OpenIddict options) and it doesn't send the id_token_hint parameter required by OpenIddict when sending a prompt=none request.
I've been following the technique outlined here:
http://blog.novanet.no/anti-forgery-tokens-using-mvc-web-api-and-angularjs/
The scenario:
I have an MVC4 application making AngularJS ajax calls a separate MVC4 WebApi application. These applications are completely separate and may eventually live on separate web servers.
What I'm seeing is that as the process goes, I can generate a token on the client (View), and then I can add a custom header attribute to be sent along with the ajax request. When the request hits the WebApi, I can see and parse out the token, but when I try to validate it, I get this message:
The provided anti-forgery token was meant for user "me", but the current user is "".
I'm thinking when I generate the token on the View, I'm building a token that relies on the currently authenticated user, and that's what get sent to the WebApi. So my question is this:
What is the standard way to lock down a WebApi when the WebApi is designed to be flexible to accept requests from a public website (anonymous access)? Do I need to build my own token mechanism that gets validated in the WebApi?
Thanks in advance!