Using AuthorizeAttribute in ASP.NET Web API - asp.net-web-api

I have used the [Authorize] attribute in an ASP.NET Web API method
[Authorize]
public IEnumerable<User> GetAllUsers()
From the application I can access this method without a problem as my user is already authenticated. However, is there any way that I can specify the username, password to this method when calling so that I can implement a REST API? This is when calling from a standalone application or the browser.

I didn't entirely understand your question but System.Web.Http.AuthorizeAttribute checks against Thread.CurrentPrincipal to see if the user is authorized or not.
You can specifically give user permissions if you want as below:
[Authorize(Users = "User1")]
public IEnumerable<User> GetAllUsers()
But the Authentication process is entirely up to you. I would recommend authenticating the user through a message handler and then populating the Thread.CurrentPrincipal there. Then, use the AuthorizeAttribute as you see fit for your application.

Related

How to handle different action with same route and different authorize attribute in asp .net core

I'm developing some Web-API project with ASP.Net Core 2 using some custom middleware which is translating the authorization info that it gets from a 3rd party service into a new Claim Identity and adds it to http context user claim principal. I also have implemented some custom authorization policy provider which checks the added claim identity for required permissions and roles.
Now I wanna have two actions like below on same controller with same route:
[Route("api/[controller]")]
public class StatesController : Controller
{
[Authorize("PaiedUser")]
[HttpGet(Name = "GetStates")]
public IActionResult GetStatesPaied(StateHttpRequestParameter requestResourceParameter)
{ //some code here to handle the paied user request}
[Authorize("FreeUser")]
[HttpGet(Name = "GetStates")]
public IActionResult GetStatesFree(StateHttpRequestParameter requestResourceParameter)
{ //some code here to handle the free user request}
}
On the runtime I got this exception,
Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:
SaMonitoring.API.Controllers.StatesController.GetStatesFree(SaMonitoring.API)
SaMonitoring.API.Controllers.StatesController.GetStatesPaied(SaMonitoring.API)
How can I achieve this behavior ?
I think the problem here is that the roles are not mutually exclusive as far as MVC is concerned. Someone could fall into both conditions which is what makes it ambiguous. I think you'd be better off checking the user's role inside a single function and providing results appropriately.

Role-based authorization in ASP.NET Web API - how to set roles on the principal?

I am using recipe 10-3 in the newly released book ASP.NET Web Api 2 Recipes to support basic authentication in my Web API. This recipe utilizes a 3rd party library from Thinktecture. As seen from the below code, I am authentication the user against my own account service.
using Thinktecture.IdentityModel.WebApi.Authentication.Handler;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
var authenticationConfiguration = new AuthenticationConfiguration();
var accountService = ServiceLocator.Get<AccountService>();
authenticationConfiguration.AddBasicAuthentication((userName, password) => accountService.Authenticate(userName, password));
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfiguration));
...
}
}
Now I want to make role-based authorization in my controllers using the Authorize attribute:
[Authorize(Roles="administrator")]
public IHttpActionResult Get()
{
...
}
My account service obviously knows about the users and their assigned roles, but this information is not available to the Authorize attibute (the roles are not set on the principal).
How do I accomplish this? Can the Thinktecture authentication handler be configured to set the roles on the principal? Or should I make my own custom Authorize attribute (deriving from the Authorize attribute)? And if so, should I override the OnAuthorization method to create and set the principal using my account service? Or maybe override the IsAuthorized method directly? Or maybe something else...
The AuthenticationHandler only does authentication. You'd need to set the roles in a separate step (e.g. in a delegating handler).
If you are on Web API v2 - I'd rather recommend switching to the basic auth OWIN middleware
https://github.com/thinktecture/Thinktecture.IdentityModel/tree/master/source/Thinktecture.IdentityModel.Owin.BasicAuthentication
This gives you full control over the principal that gets created.
https://github.com/thinktecture/Thinktecture.IdentityModel/blob/master/samples/OWIN/AuthenticationTansformation/KatanaAuthentication/Startup.cs
There is also a nuget.
I found out that the AddBasicAutentication method actually has an overload that takes a delegate for providing the roles. This is exactly what I was looking for. So now the call to AddBasicAuthentication looks like this, and everything works like a charm:
authenticationConfiguration.AddBasicAuthentication((userName, password) => accountService.Authenticate(userName, password), (username) => accountService.GetRoles(username));

Spring Security Recommended Design To Request User Login to Different User With Different Role

I have the following use case and need recommendations on the proper implementation. To be clear can this be done through configuration or do I need to implement new code?
Business Use Case
The business wants to allow a user to login via social media sites and access some of their pages. But in order to access pages that deal with $$ the user must login via the applications local account.
Technical Use Case
Allow users to login via Facebook or other provider and provide role USER_PARTIAL_RIGHTS
If user accesses a page with role USER_FULL_RIGHTS prompt the user to login to an account that is a local JDBC stored account.
This authentication must also ensure that the page is protected by USER_FULL_RIGHTS role and not other roles.
I am using grail spring security plugin, but I am expecting to have to customize the plugin.
So what are recommendations for doing this? A couple of ideas that I have are:
Technical Ideas
custom spring access denied handler
custom access denied controller instead of the stock jsp page
From what i understand from your question, here is my suggestion.
For login via Facebook use Spring Social. Here is the documentation. The implementations are straightforward. Write a custom signin method and set the authorities for partial rights, something like this:
public void signin(String userId) {
authorities = new ArrayList<GrantedAuthority>();
//set your partial rights authority
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(userId, null, authorities));
}
And do a method level security implementation using the #secured annotation to access the page that needs full rights. Something like this
#Secured("USER_FULL_RIGHTS ")
yourMethod(){
//code
}
This would prompt for a login where can use authentication from applications local account.
What we ended up implementing is a controller that looks at the role and redirects the user to the correct landing page. Kinda messy, but it works.
Collection<GrantedAuthority> inferred = SpringSecurityUtils.findInferredAuthorities(SpringSecurityUtils.getPrincipalAuthorities());
if(ifAnyGranted('ROLE_FOO', inferred)) {
redirect(controller: 'foo',action: 'home')
return
}

ASP.NET Web API and Authorization

So I have an existing Windows Phone 7 app that uses my own authorization (player logs in with an alias and password and it verifies it against a db) going to an MVC web services.
Now I'm looking to move over to ASP.NET Web API and I'm a little confused as to how to add security for it?
I see there is the AuthorizeAttribute, but what do I need to do to allow them to be authorized?
Any guidance here would be appreciated.
AuthorizeAttribute is only checking against Thread.CurrentPrincipal to see if the user authorized to access the specified resource (in this case it is controller action) or not. It doesn't provide any type of authentication mechanism.
In your case, as you have username and password in place, you can do basic authentication. Best place to do this is inside a Message Handler. Here is an example: BasicAuthenticationHandler
I don't encourage you to use this as it is because there is no test behind this implementation but this should give you an idea. That class is an abstract class and when you set this as you base class for a message handler, you need to override the AuthenticateUser method and return IPrincipal. If the return value is null, that means user is not authenticated. If you provide an IPrincipal, that IPrincipal will be set and your AuthorizeAttribute can check against it.
You can, for instance, use GenericPrincipal class to create an IPrincipal. Assuming you are on ASP.NET host, you can register your authentication handler as below:
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyAuthHandler());
To sum it up, do the authentication through a Message Handler somehow, no matter what type of authentication you use (Basic Auth, OAuth, etc.). And then, do the authorization through AuthorizeAttribute.
Also, Dominick Baier has a nice presentation on Securing ASP.NET Web
APIs and I recommend you to check that out.
maybe this will help you: Custom AuthorizeAttribute for Web API controllers

How to handle authorisation failure in MVC3

I'm building an internal (intranet) MVC3 application using Windows Authentication and a custom role provider. The authentication and role provider work okay, as long as the the user has the role requested.
For example, I have a UserContoller which allows the user of the application to manage user accounts within the application. Obviously i want to restrict access to this controller.
If I do this:
[Authorize]
public class UserController : Controller
{
...
}
then the Windows Authentication works fine, and the user is transparently logged in. However, I want to restrict the controller to a specific group of users. So I do this:
[Authorize(Roles="UserAdmin")]
public class UserController : Controller
{
...
}
If the list of roles returned by my role provider includes "UserAdmin", then everything is fine and the user gets access to the controller.
However, if the user is not in the role then the browser (tested on IE8 and FF10) prompts for credentials. If that is cancelled then the server returns a 401 error page.
So my question after all of that is, how do I handle the situation where the user is not in the requested role, and return him to the application's home action, or some other action to provide a user-friendly message?
You could also create an custom attribute which inherits from AuthorizeAttribute
Override the HandleUnauthorizedRequest method
You could specify in the web.config an url to show on the 401 case.
<customErrors mode="RemoteOnly" defaultRedirect="/Error/">
<error statusCode="401" redirect="/AuthorizationFailed"/>
</customErrors>

Resources