Acegi authentication and authorization are mainly based on two technologies: filter mechanism and AOP interception.
Mechanism. Filtersecurityinterceptor is used to implement URI protection.
The service method is blocked and the ACL is used to filter and protect prototype objects.
Httpsessioncontextintegrationfilter stores securitycontext in httpsession
Channelprocessingfilter redirects to another protocol, such as HTTP to https
Concurrentsessionfilter
Because no securitycontextholder function is used, but sessionregistry needs to be updated to indicate
Principal: registers listener in Web. XML to listen to session events, publishes relevant messages, and obtains the message elimination by sessionregistry.
To determine the number of sessions of the current user.
Authenticationprocessingfilter common authentication mechanism (most of which are used)
Casprocessingfilter CAS authentication mechanism
Basic Authentication Mechanism of basicprocessingfilter HTTP protocol
Httprequestintegrationfilter authentication obtained from httpservletrequest. getuserprincipal () of the container
Jbossintegrationfilter is related to JBoss.
Securitycontextholderawarerequestfilter is used with servlet containers.
Remembermeprocessingfilter authenticates Based on cookies.
Anonymousprocessingfilter anonymous authentication.
Exceptiontranslationfilter captures all acegi security exceptions, so either an HTTP Error Response is returned or a corresponding authenticationentrypoint is loaded.
Authenticationentrypoint authentication entry
Acegi authentication and authorization process
1. filtertobeanproxy is responsible for proxy requests to filterchainproxy
2. filterchainproxy easily concatenates multiple filters. For example, the filters mentioned in the basic concepts above can also include filtersecurityinterceptor If Uri is protected by authorization. Pay attention to the order of filters.
3. abstractsecurityinterceptor scheduling center. Calls each module to complete corresponding functions.
Filtersecurityinterceptor blocks and protects the URI
Aspectjsecurityinterceptor Blocks Methods
Methodsecurityinterceptor Blocks Methods
4. authenticationmanager User Authentication
-> Authenticationprovider refers to the locations where user authentication is performed (multiple ).
-> Userdetailsservice returns userdetail with grantedauthority or throws an exception.
5. accessdecisionmanager (unanimousbased/affirmativebased/consensusbased) Authorization
-> Accessdecisionvoter (rolevoter/baseaclentryvoter) voter (multiple ).
6. Change grantedauthority of runasmanager
7. Objects returned by afterinvocationmanager changes
-> Baseinvocationprovider: the place where the returned object changes are actually completed (multiple ).
In my project, acegi is used to control the permissions of the member system.
1. Configure web. xml
/******/Web-INF/Web. xml ******/
<? XML version = "1.0" encoding = "UTF-8"?>
<Web-app id = "webapp_id" version = "2.4"
Xmlns = "http://java.sun.com/xml/ns/j2ee"
Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
Xsi: schemalocation = "http://java.sun.com/xml/ns/j2ee
Http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd>
<Display-Name> game_proj </display-Name>
<! -- Filter supported by Chinese Language -->
<Filter>
<Filter-Name> set character encoding </filter-Name>
<Filter-class> com. popoann. setcharacterencodingfilter </filter-class>
<Init-param>
<Param-Name> encoding </param-Name>
<Param-value> GBK </param-value>
</Init-param>
</Filter>
<Filter-mapping>
<Filter-Name> set character encoding </filter-Name>
<URL-pattern>/* </url-pattern>
</Filter-mapping>
<Filter>
<! -- Acegi filter -->
<Filter-Name> acegifilterchain </filter-Name>
<Filter-class> org. acegisecurity. util. filtertobeanproxy </filter-class>
<Init-param>
<Param-Name> targetclass </param-Name>
<Param-value> org. acegisecurity. util. filterchainproxy </param-value>
</Init-param>
</Filter>
<! -- Acegi filter URL ing -->
<Filter-mapping>
<Filter-Name> acegifilterchain </filter-Name>
<URL-pattern> *. htm </url-pattern>
</Filter-mapping>
<Filter-mapping>
<Filter-Name> acegifilterchain </filter-Name>
<URL-pattern> *. jsp </url-pattern>
</Filter-mapping>
<Filter-mapping>
<Filter-Name> acegifilterchain </filter-Name>
<URL-pattern> *. DO </url-pattern>
</Filter-mapping>
<! -- Actioncontextcleanup filter -->
<Filter>
<Filter-Name> Struts-cleanup </filter-Name>
<Filter-class> org. Apache. struts2.dispatcher. actioncontextcleanup </filter-class>
</Filter>
<Filter-mapping>
<Filter-Name> Struts-cleanup </filter-Name>
<URL-pattern>/* </url-pattern>
</Filter-mapping>
<! -- Core filter of sitemesh -->
<Filter>
<Filter-Name> sitemesh </filter-Name>
<Filter-class> com. opensymphony. Module. sitemesh. Filter. pagefilter </filter-class>
</Filter>
<Filter-mapping>
<Filter-Name> sitemesh </filter-Name>
<URL-pattern>/* </url-pattern>
</Filter-mapping>
<! -- Struts core filter -->
<Filter>
<Filter-Name> struts2 </filter-Name>
<Filter-class> org. Apache. struts2.dispatcher. filterdispatcher </filter-class>
<Init-param>
<Param-Name> struts. Action. Extension </param-Name>
<Param-value> HTM </param-value>
</Init-param>
</Filter>
<Filter-mapping>
<Filter-Name> struts2 </filter-Name>
<URL-pattern>/* </url-pattern>
</Filter-mapping>
<! -- Load the springioc container when the application starts -->
<Context-param>
<Param-Name> contextconfiglocation </param-Name>
<Param-value>
/WEB-INF/beans-*. xml
</Param-value>
</Context-param>
<Listener>
<Listener-class> org. springframework. Web. Context. contextloaderlistener </listener-class>
</Listener>
<! -- Welcome page -->
<Welcome-file-List>
<Welcome-File> index.htm </welcome-File>
</Welcome-file-List>
</Web-app>
2. Configure spring Bean
/*****/Web-INF/beans-myspace_security.xml ******/
<? XML version = "1.0" encoding = "UTF-8"?>
<! Doctype beans public "-// spring // DTD bean 2.0 // en"
Http://www.springframework.org/dtd/spring-beans-2.0.dtd>
<Beans>
<! -- 1. authenticationmanager -->
<Bean id = "myspace_authenticationmanager"
Class = "org. acegisecurity. providers. providermanager">
<Property name = "providers">
<List>
<Ref bean = "myspace_daoauthenticationprovider"/>
<Ref bean = "myspace_remembermeauthenticationprovider"/>
</List>
</Property>
</Bean>
<! -- Indicates database verification through the DaO interface -->
<! -- Specify userdetailsservice, indicating that the user list is obtained by this class, and this Custom User List class is programmed later -->
<! -- Specify passwordencoder to encrypt the password in the form before verification. The MD5 Encryption Policy is used here -->
<Bean id = "myspace_daoauthenticationprovider"
Class = "org. acegisecurity. providers. Dao. daoauthenticationprovider">
<Property name = "userdetailsservice" ref = "myspace_userdetailsbo"/>
<Property name = "passwordencoder" ref = "myspace_passwordencoder"/>
</Bean>
<Bean id = "myspace_passwordencoder"
Class = "org. acegisecurity. providers. encoding. md5passwordencoder"/>
<! -- Indicates verification through cookies -->
<Bean id = "myspace_remembermeauthenticationprovider"
Class = "org. acegisecurity. providers. rememberme. remembermeauthenticationprovider">
<Property name = "key" value = "myspace_remember_me"/>
</Bean>
<! -- 2. accessdecisionmanager -->
<Bean id = "myspace_accessdecisionmanager"
Class = "org. acegisecurity. Vote. affirmativebased">
<Property name = "decisionvoters">
<List>
<Bean class = "org. acegisecurity. Vote. rolevoter"/>
</List>
</Property>
<Property name = "allowifallabstaindecisions" value = "false"/>
</Bean>
<! -- 3. Configure the interceptor chain -->
<Bean id = "myspace_filterchainproxy" class = "org. acegisecurity. util. filterchainproxy">
<Property name = "filterinvocationdefinitionsource">
<Value>
Pattern_type_apache_ant
/MySpace/*. htm * = myspace_httpsessioncontextintegrationfilter, myspace_logoutfilter, myspace_authenticationprocessingfilter, myspace_remembermefilter, myspace_exceptionfilter, myspace_securityinterceptor
/** = Myspace_httpsessioncontextintegrationfilter, myspace_logoutfilter, myspace_authenticationprocessingfilter, myspace_remembermefilter, myspace_exceptionfilter, myspace_securityinterceptor
</Value>
</Property>
</Bean>
<! -- (1) Session verification interceptor -->
<Bean id = "myspace_httpsessioncontextintegrationfilter"
Class = "org. acegisecurity. Context. httpsessioncontextintegrationfilter"/>
<! -- (2) deregister the function interceptor -->
<Bean id = "myspace_logoutfilter"
Class = "org. acegisecurity. UI. logout. logoutfilter">
<! -- Default jump page after cancellation -->
<Constructor-Arg value = "/login.htm"/>
<Constructor-Arg>
<List>
<Ref bean = "myspace_remembermeservices"/>
<Bean class = "org. acegisecurity. UI. logout. securitycontextlogouthandler"/>
</List>
</Constructor-Arg>
<! -- User logout URL -->
<Property name = "filterprocessesurl" value = "/j_logout.do"/>
</Bean>
<! -- (3) -->
<Bean id = "myspace_authenticationprocessingfilter"
Class = "org. acegisecurity. UI. webapp. authenticationprocessingfilter">
<Property name = "authenticationmanager" ref = "myspace_authenticationmanager"/>
<! -- Logon Failure page, which usually contains error information -->
<Property name = "authenticationfailureurl" value = "/login! Error.htm "/>
<! -- Jump to the page by default after logon -->
<Property name = "defaulttargeturl" value = "/MySpace/hellouser.htm"/>
<! -- User Logon URL -->
<Property name = "filterprocessesurl" value = "/j_login.do"/>
<Property name = "remembermeservices" ref = "myspace_remembermeservices"/>
</Bean>
<! -- (4) Cookies verification interceptor -->
<Bean id = "myspace_remembermefilter"
Class = "org. acegisecurity. UI. rememberme. remembermeprocessingfilter">
<Property name = "authenticationmanager" ref = "myspace_authenticationmanager"/>
<Property name = "remembermeservices" ref = "myspace_remembermeservices"/>
</Bean>
<Bean id = "myspace_remembermeservices"
Class = "org. acegisecurity. UI. rememberme. tokenbasedremembermeservices">
<Property name = "userdetailsservice" ref = "myspace_userdetailsbo"/>
<Property name = "parameter" value = "myspace_remember_me"/>
<Property name = "key" value = "myspace_remember_me"/>
<Property name = "tokenvalidityseconds" value = "31536000"/>
</Bean>
<! -- (5) -->
<Bean id = "myspace_exceptionfilter"
Class = "org. acegisecurity. UI. exceptiontranslationfilter">
<! -- Logon entry in case of authenticationexception -->
<Property name = "authenticationentrypoint">
<Bean class = "org. acegisecurity. UI. webapp. authenticationprocessingfilterentrypoint">
<Property name = "loginformurl" value = "/login.htm"/>
<Property name = "forcehttps" value = "false"/>
</Bean>
</Property>
<! -- Specify the error page. When the current role cannot access this resource, locate the error page. -->
<! -- Handler in case of accessdeniedexception -->
<Property name = "accessdeniedhandler">
<Bean class = "org. acegisecurity. UI. accessdeniedhandlerimpl">
<Property name = "errorpage" value = "/error. jsp"/>
</Bean>
</Property>
</Bean>
<! -- (6) security interceptor, integrating authentication and decision manager, and defining roles corresponding to various directory structures. Ant expressions are available -->
<Bean id = "myspace_securityinterceptor"
Class = "org. acegisecurity. Intercept. Web. filtersecurityinterceptor">
<Property name = "authenticationmanager" ref = "myspace_authenticationmanager"/>
<Property name = "accessdecisionmanager" ref = "myspace_accessdecisionmanager"/>
<Property name = "objectdefinitionsource">
<Value>
Pattern_type_apache_ant
/MySpace/sales _ *. htm * = role_sales_user
/MySpace/provide _ *. htm * = role_provide_user
</Value>
</Property>
</Bean>
</Beans>
Pay attention to the filter configuration sequence and more filters, but the above is sufficient.
3. Compile the userdetails class
/****** Myspace_userdetailsbo.java ******/
Package Bo;
Import org. acegisecurity. userdetails. userdetailsservice;
Import org. acegisecurity. userdetails. userdetails;
Import org. acegisecurity. userdetails. user;
Import org. acegisecurity. userdetails. usernamenotfoundexception;
Import org. springframework. Dao. dataaccessexception;
Import org. acegisecurity. grantedauthorityimpl;
Import org. acegisecurity. grantedauthority;
Import Bo. userbo;
Import java. util .*;
Public class userdetailsbo implements userdetailsservice {
// Define two roles
Private Final grantedauthority role_sales_user = new grantedauthorityimpl ("role_sales_user ");
Private Final grantedauthority role_provide_user = new grantedauthorityimpl ("role_provide_user ");
Private userbo Bo;
Private model. User user;
Private list <model. User> myusers;
Private Map <string, string> Users = new hashmap <string, string> ();;
Private grantedauthority [] authorities;
// When injecting Business Objects, copy the user list to a hashmap object in sequence.
Public void setbo (userbo Bo ){
This. BO = bo;
Myusers = bo. getuserlist ();
Users. Put ("test", "test ");
For (model. User: myusers ){
Users. Put (user. GetUserName (). Trim (), user. GetPassword (). Trim ());
System. Out. println (user. GetUserName (). Trim () + "=" + User. GetPassword (). Trim ());
}
}
Public userdetailsbo (){
}
/* This interface method must be implemented. The modified method indicates whether the user exists before verification. If the user does not exist, verification is not necessary. If the user exists, for the username obtained through the form, the password must be compared with the username value in the hashmap defined in this class, and then verified based on Spring bean configuration */
Public userdetails loaduserbyusername (string username)
Throws usernamenotfoundexception, dataaccessexception {
// Todo auto-generated method stub
System. Out. println (username );
String Password = users. Get (username );
If (Password = NULL)
Throw new usernamenotfoundexception ("No such user ");
System. Out. println (password );
If (BO. getuser (username). GetType () = 1)
Authorities = new grantedauthority [] {role_sales_user };
Else
Authorities = new grantedauthority [] {role_provide_user };
Return new user (username, password, true, authorities );
}
}
4. Create a logon form based on the configuration
<Table width = "167" Height = "80" border = "0" cellpadding = "0" cellspacing = "0">
<Form onsubmit = "Return dovalidate ('_ login')" id = "_ login" name = "_ login" method = "Post" Action = "j_login.do">
<Tr class = "style3">
<TD width = "60" align = "right" class = "style3"> <SPAN class = "style9 style3"> User name: </span> </TD>
<TD width = "107"> <input name = "j_username
"Type =" text "class =" style9 "id =" j_username "size =" 15 "/> </TD>
</Tr>
<Tr class = "style3">
<TD align = "right" class = "style3"> <SPAN class = "style9
Style3 "> password & nbsp; Code: </span> </TD>
<TD> <input name = "j_password
"Type =" password "class =" style9 "id =" j_password "size =" 15 "/> </TD>
</Tr>
<Tr class = "style3">
<TD colspan = "2" align = "center"> <Table width = "100%" Height = "27" border = "0" cellpadding = "0" cellspacing = "0">
<Tr>
<TD align = "center" class = "style2"> <input style ="
Background-image: URL (images/btnbg.gif); width: 67px; Height: 22px"
Type = "Submit" name = "Submit" value = "Logon"/> <input type = "checkbox"
Name = "myspace_remember_me
"/>
Remember users </TD>
</Tr>
</Table> </TD>
</Tr>
</Form>
</Table>
Note that the username and password fields must be j_username, j_password, and myspace_remember_me.
It corresponds to the key attribute of the bean myspace_remembermeauthenticationprovider in spring bean configuration.
At this point, security verification is complete.