Shiro Authentication authorized Source code Analysis

Source: Internet
Author: User
Tags error code inheritance

Shiro has a number of filters built in to control authentication authorization

Anon:org.apache.shiro.web.filter.authc.AnonymousFilter

Authc:org.apache.shiro.web.filter.authc.FormAuthenticationFilter

AuthcBasic:org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

Perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

Port:org.apache.shiro.web.filter.authz.PortFilter

Rest:org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

Roles:org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

Ssl:org.apache.shiro.web.filter.authz.SslFilter

User:org.apache.shiro.web.filter.authc.UserFilter


Where authentication is logged in Formauthenticationfilter

Authentication Authorization (roles, permissions) Rolesauthorizationfilter,permissionsauthorizationfilter

(Take Rolesauthorizationfilter as an example below)

The core is inherited from Accesscontrolfilter

On the left is the authentication login, the right is the authentication authorization. Note that the red box position Formauthenticationfilter and rolesauthorizationfilter all pass through the transition class inherits from the Accesscontrolfilter

A brief introduction to some of the methods of this class

Onprehandle: Determine if the certification passed, and subsequent processing of the code:

public boolean onprehandle (ServletRequest request, servletresponse response, Object mappedvalue) throws Exception {
return isaccessallowed (Request, Response, Mappedvalue) | | OnAccessDenied (Request, response, mappedvalue);
}

isaccessallowed: Determine whether the authentication is passed (Formauthenticationfilter is the authentication is signed in, Rolesauthorizationfilter is the authentication is authorized)

OnAccessDenied: Subsequent processing of authentication failures

Isloginrequest: To determine if a logon request has been made, the login address is in the configuration file:

<!--not logged in, Access AUTHC enters the path of the loginurl configuration--
<property name= "loginurl" value= "/login" ></property>
<!--The default address of the jump after successful login--
<property name= "Successurl" value= "/main" ></property>
<!--if the resource you requested is no longer your permission range, jump to/400 request address--
<property name= "Unauthorizedurl" value= "></property>"

Saverequest: Save current request

Redirecttologin: Redirect to login page

Saverequestandredirecttologin: Save the current request and redirect to the login page

The authentication login process follows the inheritance relationship:

Accesscontrolfilter

public boolean onprehandle (ServletRequest request, servletresponse response, Object mappedvalue) throws Exception {
return isaccessallowed (Request, Response, Mappedvalue) | | OnAccessDenied (Request, response, mappedvalue);
}

Authenticatingfilter (determines if authentication is passed, the parent class will be called isaccessallowed)

@Override
Protected Boolean isaccessallowed (ServletRequest request, servletresponse response, Object mappedvalue) {
return super.isaccessallowed (Request, Response, Mappedvalue) | |
(!isloginrequest (Request, Response) && ispermissive (Mappedvalue));
}

Authenticationfilter (here to really determine if you are logged in)

Protected Boolean isaccessallowed (ServletRequest request, servletresponse response, Object mappedvalue) {
Subject Subject = getsubject (request, response);
return subject.isauthenticated ();
}

If you log in, skip directly if you are not logged in:

Formauthenticationfilter

Protected Boolean onaccessdenied (ServletRequest request, servletresponse response) throws Exception {
if (isloginrequest (request, response)) {
if (isloginsubmission (request, response)) {
if (log.istraceenabled ()) {
Log.trace ("Login submission detected. Attempting to execute login. ");
}
return Executelogin (request, response);
} else {
if (log.istraceenabled ()) {
Log.trace ("Login Page view.");
}
Allow them to see the login page;)
return true;
}
} else {
if (log.istraceenabled ()) {
Log.trace ("Attempting to access a path which requires authentication. Forwarding to the "+
"Authentication URL [" + Getloginurl () + "]");
}

Saverequestandredirecttologin (request, response);
return false;
}
The first step is to determine if the login request is a Get Form login page to continue the filter chain, if the post form is submitted to execute the Executelogin method,

Go to the Dogetauthenticationinfo method in realm.

PS: Authenticationtoken is generated during the execution of the Executelogin method, the specific code:

Protected Authenticationtoken Createtoken (string Username, string password,
ServletRequest request, servletresponse response) {
Boolean rememberme = Isrememberme (request);
String host = gethost (request);
Return Createtoken (username, password, rememberme, host);
The default is Username,password, so the foreground page Name property should correspond.

Login success or failure will go onloginsuccess or onloginfailure

Save the current request to the login page if it is not a login request, and customize your own formauthenticationfilter if you want to encapsulate the Shiro processing of the AJAX request


The authentication authorization process follows the inheritance relationship

Accesscontrolfilter

public  Boolean onprehandle (servletrequest request, servletresponse response,  Object mappedvalue)   throws exception {
        return  Isaccessallowed (request, response, mappedvalue) | |  onaccessdenied (Request, response, mappedvalue);
  &NBSP;} Rolesauthorizationfilter (authentication is granted, Shiro default is required for all roles to be authenticated)

public boolean isaccessallowed (ServletRequest request, servletresponse response, Object mappedvalue) throws IOException {

Subject Subject = getsubject (request, response);
String[] Rolesarray = (string[]) Mappedvalue;

if (Rolesarray = = NULL | | rolesarray.length = = 0) {
No roles specified, so nothing to check-allow access.
return true;
}

set<string> roles = Collectionutils.asset (Rolesarray);
return subject.hasallroles (roles);
}

Authorizationfilter (processing after the authentication role has not passed)

Protected Boolean onaccessdenied (ServletRequest request, servletresponse response) throws IOException {

Subject Subject = getsubject (request, response);
If the subject isn ' t identified, redirect to login URL
if (subject.getprincipal () = = null) {
Saverequestandredirecttologin (request, response);
} else {
If subject is known and not authorized, redirect to the unauthorized URL if there is one
If No unauthorized URL is specified, just return an unauthorized HTTP status code
String Unauthorizedurl = Getunauthorizedurl ();
Shiro-142-ensure that redirect _or_ error code Occurs-both cannot happen due to response commit:
if (Stringutils.hastext (Unauthorizedurl)) {
Webutils.issueredirect (Request, response, Unauthorizedurl);
} else {
Webutils.tohttp (response). Senderror (httpservletresponse.sc_unauthorized);
}
}
return false;
}

If not logged in, save the current request to jump to the login page, otherwise determine if there is a request to configure the authentication permission does not pass the need to jump, if configured to jump, or throw an error code sc_unauthorized (401), you can capture the error code in Web. XML to define the page to jump.


This is my understanding of the Shiro Authentication authorization policy, where authentication authorization before and after the processing can be done by inheriting the corresponding class reproduction method to achieve the custom effect, do not need to write redundant business logic code in the Contrller layer, Shiro these interfaces and related configuration files can help you get it done.

Finally, you need to configure it in the Shiro configuration file

< Bean id = "Shirofilter" class = "Org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
< property name = "SecurityManager" ref = "SecurityManager"/>
<!--access AUTHC is not logged in, the path to the loginurl configuration is entered--
< property name = "Loginurl" value = "/login" ></property >
<!--The default address of the jump after successful login--
< property name = "Successurl" value = "/main" ></property >
<!--if the resource you requested is no longer your permission range, jump to/400 request address--
< property name = "Unauthorizedurl" value = "$" ></property >
09<property name= "Filters" >
Ten <map>
<entry key= "AUTHC" >
<bean class= "Com.luming.shiro.MyFormAuthenticationFilter"/>
</entry>
<entry key= "Roles" >
<bean class= "Com.luming.shiro.MyRolesAuthorizationFilter"/>
</entry>
</map>
</property>

</Bean >

Myformauthenticationfilter inherited from Formauthenticationfilter

Myrolesauthorizationfilter inherited from Rolesauthorizationfilter

Finally, the Shiro custom authentication authorization based on its own project also needs to be combined with the custom realm:Shiro authentication Authorization

Because Jdbcrealm's dogetauthenticationinfo defines how the data submitted by the user is authenticated, Dogetauthorizationinfo defines what permissions are granted to the user.

and Formauthenticationfilter and Rolesauthorizationfilter are mainly responsible for the authentication and authorization of the need to do some of the custom operations, such as IP filtering

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.