getting authorization code from url - c#

When using oauth I can get an authorization code returned in the URL to me but i don't know how to get that code out of the url. For example when i give the app permission to run i get
http://localhost/?code=moBOuHmeCj.KUjTq14iwVyywiLbB44SNZ4-olDb2uFmXOwPpFzV.PQUHfFCNKAqStMp8.NMDZPjEZMJosDMC0JKZip.qHTvQ5KHI9oFIGwNh79EabwklUQjVgXzrc4Mor6mcmMRVTJTos3mv2BzIEw%3D%3D
as a response but i need to get that out of the browser and back to the server to get the long access key.How do i do this?

Set your authentication provider's returnUrl as a specific route of your site, something like http://localhost/oauth
In your OAuthController (I'm assuming your question is about a MVC app) use:
public ActionResult Index(string code)
{
// Perform any action related with 'code' value provided by auth provider.
}

Please try this code:
$code = $_GET['code'];

Related

ASP.NET Core - Preserve POST data after Authorize attribute login redirect

This is essentially the same question as this one:
ASP.NET MVC - Preserve POST data after Authorize attribute login redirect except it isn't asked 7 years ago, and it's about ASP.NET Core, which is pretty different. I am using the [Authorize] attribute to do my most basic access authentication, really just to check to see if there is a user logged in at all. If not, then it kicks them back to the login page. Here's the services setup for that.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "loginId";
});
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/Logout");
Here is my Logout action.
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Logout(string returnUrl = "/cgi-s/admin.cgi")
{
await HttpContext.SignOutAsync();
if (HttpContext.Request.Cookies.TryGetValue("loginId", out string loginId))
{
User auth = _context.Users.Where(a => a.LoginId.Equals(loginId)).FirstOrDefault();
if (auth != null)
{
auth.LoginId = string.Empty;
await _context.SaveChangesAsync();
}
}
return Redirect("/Account/Login?returnUrl="+returnUrl);
}
Right now I am just using the default behavior with a return url string to get back to the attempted page after a successful login. Is there a way to set this up so that POST data is also preserved?
I've tried a couple different things, like a custom middleware that stores post data which then gets retrieved on login, but I haven't come up with anything that I haven't found security holes in afterward.
Is there an easy way to do this that I'm just missing?
Thanks.
PS. Please ignore the weirdness going on in the Logout action. We are a two man team working on a 20 year old Perl CGI site, slowly transitioning over to .NET while trying to also keep up with new features and bug fixes, so everything is weird while we run Perl CGI alongside some .NET code on IIS with Postgres. Hopefully we will eventually get everything transitioned over.
Have you tried httpContext.Request.EnableBuffering?
See this question here and be sure to look at the comments: Read the body of a request as string inside middleware
httpContext.Request.EnableBuffering();
using(StreamReader streamReader = new StreamReader(httpContext.Request.Body,
...,leaveOpen: true))
{
//Do something here:
httpContext.Request.Body.Position = 0;
}

Abort connection in case of Unauthorized JWT sent in http request to Web API .net Core 2

I am writing a .net Core 2.0 Web API controller that performs file upload using a multipart type http request and is based in the streaming technique described here.
At this point I have to say that I if you want you can skip the next two paragraphs that describe the reason that led me to the need for a solution to the problem that is described after the two paragraphs.
I initially thought of authenticating the user by sending authentication data in the first section of the multipart request and validating the user as soon as the user data are read, by contacting the database and performing the proper request. However, I thought that since this is a streaming request, any delay in authenticating the user using the database, would delay reading the stream with the file. This would cause the TCP receive buffer to fill with data (possibly also increase its size) and would defeat the purpose of streaming the file (instead of buffering), since memory consumption for this connection would increase.
In order to get rid of this issue I thought of using a 2 step authentication using JWTs. The Web API user will first perform a request and ask for a JWT. Then it would use this JWT in the upload request. As I understand it, JWT authentication should be much faster than a database request since it is performed by validating the JWT using the key stored in the server, so the previous issue should not exist.
I implemented the JWT authentication for the upload request following this very good description from Auth0 and it worked just fine. More specifically the controller has an [Authorize] attribute that forces Web API to to authenticate the user by validating the JWT before the controller is executed.
The problem I am facing is that with the above proposed solution when an unauthorized user tries to upload a file the Controller action is never called. The Authentication engine returns an Unathorized (401) response to the user and lets the user continue sending file data. The last part is my problem. I would like unauthorized users, which are probably attackers, to receive the 401 response and then have their connection terminated.
So, what I want is to keep the authentication/authorization part as it already works and also terminate the user connection after sending the 401 response. I know (and have also tested it) that from inside a controller action method an http connection can be terminated by calling
HttpContext.Abort();
I suspect that by using a filter, I could do what I want but I am not very familiar with filters so that is why I am asking.
We can achieve that by using an IAuthorizationFilter.
Inside it, we gonna set an special ActionResult called AbortUnauthorizedConnectionResult and in that we set the Status Code to 401 and Content-Length to 0 and by calling Response.Body.Flush() we make sure it's sent to client before we call Abort().
Here we have an AuthorizationFilter called AbortUnauthorizedConnections:
class AbortUnauthorizedConnections : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
if (context.HttpContext.User?.Identity == null || !context.HttpContext.User.Identity.IsAuthenticated)
{
// by setting this we make sure the pipe-line will get short-circuited.
context.Result = new AbortUnauthorizedConnectionResult();
}
}
}
And because we have inherited from Attribute we can use it on the upload action like this:
[Authorize]
[AbortUnauthorizedConnections]
public async Task<IActionResult> UploadFile()
{
// we do whatever we want.
}
Here is the code for AbortUnauthorizedConnectionResult:
class AbortUnauthorizedConnectionResult : StatusCodeResult
{
public AbortUnauthorizedConnectionResult() : base(401)
{
}
public override async Task ExecuteResultAsync(ActionContext context)
{
await base.ExecuteResultAsync(context);
context.HttpContext.Response.Headers.Add("Content-Length", "0");
context.HttpContext.Response.Body.Flush();
context.HttpContext.Abort();
}
}
Now if an unauthorized user try to access this controller will get 401 and it's connection gets aborted.
This is the solution I actually implemented due to its simplicity, following #Tratcher's advice:
First, I deleted the [Authorize] attribute from my Controller Action method. Then I wrote the beginning of my Controller Action method as follows:
public async Task<string> UploadFile()
{
if (!(await HttpContext.AuthenticateAsync()).Succeeded)
{
HttpContext.Response.StatusCode = 401; //Unauthorized
HttpContext.Response.Headers.Add("Content-Length", "0");
HttpContext.Response.Body.Flush();
HttpContext.Abort();
return null;
}
...
}

web api get user info inside controller

I'm using the standard owin asp.net.identity mechanism to authorize users using their access token. Inside my controller I would like to find out who has sent the request. How could I do it? Could I somehow retrieve the access token from the request inside my controller?
I have tried:
public HttpResponseMessage Get([FromUri] GetParameters parameters)
{
Var identity = RequestContext.Principal.Identity;
}
It does not give me a lot as majority of properties are always null.
try
string token = HttpContext.Current.Request.LogonUserIdentity.Token.ToString();

Get the current user, within an ApiController action, without passing the userID as a parameter

How do we get the current user, within an secure ApiController action, without passing the userName or userId as a parameter?
We assume that this is available, because we are within a secure action. Being in a secure action means that the user has already authenticated and the request has her bearer token. Given that WebApi has authorized the user, there may be a built in way to access the userId, without having to pass it as an action parameter.
In WebApi 2 you can use RequestContext.Principal from within a method on ApiController
You can also access the principal using the User property on ApiController.
So the following two statements are basically the same:
string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Hint lies in Webapi2 auto generated account controller
Have this property with getter defined as
public string UserIdentity
{
get
{
var user = UserManager.FindByName(User.Identity.Name);
return user;//user.Email
}
}
and in order to get UserManager - In WebApi2 -do as Romans (read as AccountController) do
public ApplicationUserManager UserManager
{
get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
}
This should be compatible in IIS and self host mode
None of the suggestions above worked for me. The following did!
HttpContext.Current.Request.LogonUserIdentity.Name
I guess there's a wide variety of scenarios and this one worked for me. My scenario involved an AngularJS frontend and a Web API 2 backend application, both running under IIS. I had to set both applications to run exclusively under Windows Authentication.
No need to pass any user information. The browser and IIS exchange the logged on user credentials and the Web API has access to the user credentials on demand (from IIS I presume).
Karan Bhandari's answer is good, but the AccountController added in a project is very likely a Mvc.Controller. To convert his answer for use in an ApiController change HttpContext.Current.GetOwinContext() to Request.GetOwinContext() and make sure you have added the following 2 using statements:
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
In .Net Core use User.Identity.Name to get the Name claim of the user.
If you are using Asp.Identity UseManager, it automatically sets the value of
RequestContext.Principal.Identity.GetUserId()
based on IdentityUser you use in creating the IdentityDbContext.
If ever you are implementing a custom user table and owin token bearer authentication, kindly check on my answer.
How to get user context during Web Api calls?
Hope it still helps. :)
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null
&& HttpContext.Current.User.Identity.Name != null)
{
userName = HttpContext.Current.User.Identity.Name;
userId = HttpContext.Current.User.Identity.GetUserId();
}
Or based on Darrel Miller's comment, maybe use this to retrieve the HttpContext first.
// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);
See also:
How to access HTTPContext from within your Web API action

How to use ServiceStack authentication correctly in ASP.Net MVC controller

I'm having problem with getting ServiceStack [Authentication] attribute to work in ASP.Net MVC4 controller, pages / action methods with the attribute keep redirecting Users to the login page even after the login details are submitted correctly.
I've followed the SocialBootstrapApi example, with the difference being that all the authentication web service calls are made from the controllers:
this.CreateRestClient().Post<RegistrationResponse>("/register", model);
Other things that I've done so far:
Use my own user session implementation subclassing AuthUserSession (not too different from the example, but using my own implementation of User table)
Inherit ServiceStackController on my BaseController, overriding the default login URL
Enable Auth feature in AppHost with my user session implementation
Registration does work, user auth logic works (even though the session does not persist), and I can see the ss-id and ss-pid cookies in the request.
So my complete list of questions:
How do I make the [Authenticate] attribute work (or, what did I do wrong)?
How do I save and reuse the user session in an MVC controller? At the moment this.UserSession is always null.
How do I logout a user? this.CreateRestClient().Get<AuthResponse>("/auth/logout"); does not seem to work.
Update 1:
The session cookies (ss-id and ss-pid) gets created when I attempt to load the secured page (ones with [Authenticate] attribute), before any credentials get submitted. Is this the expected behaviour?
Update 2:
I can see that the session is saved in MemoryCacheClient, however trying to retrieve it in the base controller via this.Cache.Get<CustomUserSession>(SessionKey) returns null (where SessionKey is like: urn:iauthsession:1)
After much fiddling around, apparently the way to hook ServiceStack authentication is to call the AuthService via:
try {
authResponse = AuthService.Authenticate(new Auth{ UserName = model.UserName, Continue = returnUrl, Password = model.Password });
} catch (Exception ex) {
// Cut for brevity...
}
and NOT authResponse = this.CreateRestClient().Post<AuthResponse>("/auth/credentials", model);!
Where AuthService is defined in the base controller as:
public AuthService AuthService
{
get
{
var authService = ServiceStack.WebHost.Endpoints.AppHostBase.Instance.Container.Resolve<AuthService>();
authService.RequestContext = new HttpRequestContext(
System.Web.HttpContext.Current.Request.ToRequest(),
System.Web.HttpContext.Current.Response.ToResponse(),
null);
return authService;
}
}
Everything else (incl. session) works correctly now.
You can find how it could be done in the ServiceStack Use Cases repository. The following example is based on MVC4 but works perfectly for MVC3 either: CustomAuthenticationMvc.

Categories

Resources