Authorization on Dynamic Web API Controllers - aspnetboilerplate

How to use AbpAuthorize or AbpAllowAnonymous attributes?
What's the default behaviour for these controllers?
Could not find in docs.

AbpAuthorize is just used to check for permissions. This for example:
[AbpAuthorize("Administration.UserManagement.CreateUser")]
public void CreateUser(CreateUserInput input)
{
//A user can not execute this method if he is not granted for "Administration.UserManagement.CreateUser" permission.
}
Checks if he has the Administration.UserManagement.CreateUserpermission. Before allowing the user to execute the method.
AbpAuthorize, if left without parameters just checks if the user is logged in.
[AbpAuthorize]
public void SomeMethod(SomeMethodInput input)
{
//A user can not execute this method if he did not login.
}
This for example, will check if the user is logged in before he can execute the method.
Try reading here for more detailed stuff:
https://aspnetboilerplate.com/Pages/Documents/Authorization#DocCheckPermission
It will explain it better than me.

You can add these attributes to your Application Services or Controllers derived from AbpController. Basically it uses interception and checks the current user has the required permission or not. (Hence an authenticated user is needed to check a permission). So first you have to authenticate the user to dive into these permissions.

Related

Multiple middlewares do not work as wanted

If I have 3 user roles (head, admin and moderator):
I want to allow head to all methods, admin to most methods and moderator to one method.
Inside InstitutionsController:
public function __construct() {
$this->middleware('head');
$this->middleware('admin')->only(['index', 'create']);
$this->middleware('moderator')->only(['index']);
}
By this I cannot open visit index method as moderator or admin, just as head...
How can I achieve this?
BTW my middlewares have: return !auth()->user()->isAdmin()?redirect()->home():$next($request) etc for other 2
You need to read up on middleware. They are classes that manipulate HTTP requests and responses. A request comes in, a response comes out. They’re processed one at a time. So if you have a middleware that checks a role, it’s going to check that role and throw an “Unauthorized” response if the user does not have that role.
As such, checking if a user can do something is not the job of middleware (as you have found). If you want to check a user can do something, use a policy around your resource instead.
The Authorization documentation has more information on creating policies and authorizing actions in your Laravel applications.

Escaping a few views from authentcation (Guest Users) in Django-rest-framework

I've set a default authentication class as I needed most of apis to be authenticated before being accessible. However, I need login api to be available to all user.
I don't see negative authentication class in django-rest-framework.
How do I let my login api to be available to guest users while not making view level authentication_classes declarations?
This problem arose because I'm not using django's User model. How do I create AnonymousUser instance for my custom User model (not inherited from django's user model) and then permit that user to interact with the apis?
EDIT
Mark Galloway reminded me of mentioning the same issue with permission_classes.
Authentication alone does not prevent a user from accessing resources. A combination of authentication and permissions is the actual determiner for this. For example, if your permissions are set to 'permissions.IsAuthenticatedOrReadyOnly' then users who fail to authenticate (eg/ no valid token) can still access the retrieve and list endpoints.
How exactly you want to define your permissions is up to you. For most of my implementations I use a global permissions setting but tag my log in endpoint with view-level AllowAny permissions. Additionally, view-level authentication for a specific is the only way to override global authentication settings.
For example:
class login(viewsets.GenericViewSet):
permission_classes = (permissions.AllowAny,)

JSP/Tomcat secure login with sessionstorage

I have a system running on Tomcat, with HTML/JSP in front-end, and java/Spring/Struts in backend.
I made a login-feature where the user enters his username and password.
In backend, I validate the username and password to the stored user in DB.
If match, I store the username in HTTPsession:
session.setAttribute( "username", name );
Then, on every class-action in backend, I add the following code:
HttpSession session = request.getSession();
if(session.getAttribute("username") == null) {
return mapping.findForward("invalidUser");
}
the invalidUSer-mapping redirects the user back to the login-page.
How secure is this?
Is there a way to check the httpsession without adding my validation-code to every class?
Do you guys have tips (or examples/tutorials) on how to do this differently? The system is already created and in production, so I do not want to do too many architecural changes.
As you are already using Spring in your project, you may want to look into Spring Security to replace your bespoke security mechanisms. You can configure it to protect certain resources within your application, authenticate against bespoke database back-ends, LDAP directories, etc. This will allow you to remove all manual checking of the session to see if the user is authenticated, and will redirect anonymous users to the specified login page when they attempt to access protected resources.
Along with the spring security filter definition in web.xml, the configuration can be specified in a single spring-security.xml file (imported into your root app config) using the security:http namespace to define the login page, protected resources, logout page, security headers etc. You could use a org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl instance configured as a bean to define the user service which can be referenced by the authentication-provider - see the docs, its very flexible.
Hope that's useful.

How to implement one controller mapping method for different scenarios

I have a spring controller method which could be called in different scenarios. here is the example...
#RequestMapping("/resetpassword")
public ModelAndView resetpassword( #Valid #ModelAttribute("resetpasswordForm") ResetPawdFormForm resetPawdFormForm, ModelAndView modelAndView){
... this method could be executed in 3 different scenarios....
using the hyper link coming from the user reset password link sent to user email..
eg: localhost/myApp/login/resetpassword//
Here I can authenticate userID and activationSecretCode in DB and let user reset password
user can click on resetpassword link from user settings page.
eg: Since the user is already coming from user settings page, I can validate userSession and allow him to reset password
User can login for first time successfully, but are forced to reset password due to admin requirements for reset initial default password.
eg: in this user neither have session, nor passing any activationcode to validate.
login method validates userid/default password and redirects to resetpassword mapping(method=GET).
How can the system authenticate the user request and allow him to reset password?
One alternative for this is, to use flash attributes and set a authenticationKey as flash attributes...which could be verified in resetpassword method.
is there other way to implement this....
Note: I posted an issue in implementing this approach in
Post: Spring: How to pass Java objects during redirect while using ModelAttribute
Any help?
I think the best way to implement this is using three different action methods:
resetPassword (e-mails)
resetLoggedUserPassword (via settings)
changeDefaultPassword
They may even share the same view, but the behaviors are not equal, so I would avoid overloading the action responsibility.
EDIT: elaborating on your comment:
1) To secure the e-mail link, one way is to add a authentication token. The token can be as weak as a hashed user id plus some salt string, or as strong as a GUID with expiration time in a database table, generated whenever a user requests a password reset.
2) The settings way is not a problem, considering that the user is already logged in.
3) The temporary password action can be secured the same way as 1, or the same way as 2, if you put the user on the session. Logging in the user even with the default password status shouldn't be a concern if the code that verify the status of the account are inside a request filter.

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
}

Resources