These days are engaged in spring Security + memecached development.
Encountered a problem:
User information is stored in memcached through Spring security certification,
Loginsuccesshandler.java
public void onauthenticationsuccess (HttpServletRequest request,
httpservletresponse response, authentication Auth) throws IOException,
servletexception {securityuser suser
= (securityuser) auth.getprincipal ();
Write the user object after login to memcached
setcookies (Request, response, suser);
Request.getsession (). setattribute (Constantvalues.login_user_session, suser);
result is = new result (URL, true, null);
Objectmapper mapper = new Objectmapper ();
Response.setcontenttype ("Application/json;charset=utf-8");
Response.setcharacterencoding ("UTF-8");
Response.setheader ("Cache-control", "No-cache");
Mapper.writevalue (Response.getwriter (), result);
}
Then, the user passes the loginfilter when accessing the URL,
The main function of this filter is to judge the session there is no user information, not from the memcached inside take.
Loginfilter.java
</pre><pre name= "code" class= "java" > Public void Dofilter (ServletRequest request, Servletresponse Response,
Filterchain chain) throws IOException, servletexception {
//...
.. HttpSession session = Httpservletrequest.getsession ();
Securitycontextholder.getcontext (). Getauthentication (); has been the anonymous state
securityuser suser = (securityuser) session.getattribute (constantvalues.login_user_session);
if (suser!= null) {
log.info ("Authenticated by user in session");
Chain.dofilter (request, response);
else{
suser = Memcachedservice.getuser ();
if (suser!= null) {
log.info ("The user in memcached has passed authentication, save session Again");
Session.setattribute (Constantvalues.login_user_session, suser);
Chain.dofilter (request, response);
else{
log.info ("Authentication failed, session and memcached users do not exist");
Session.invalidate ();
Redirecttologinpage (HttpServletRequest, HttpServletResponse, "/j_spring_security_logout");}}
Originally thought this writes, no big problem.
It turns out that after restarting Tomcat, Memcached gets the user's information,
But spring Security's Securitycontextholder.getcontext (). Getauthentication (); All the time, the anonymous state was taken.
Causes the home page header to display user information. But clicking on the specific admin menu always jumps to the unauthorized page (spring security does not intercept the URL of the home page)
There's no clue what to think.
Finally, you can only customize the authorization class.
Package cn.syher.system.security;
Import java.util.Collection;
Import Java.util.Iterator;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.beans.factory.annotation.Value;
Import Org.springframework.security.access.AccessDecisionManager;
Import org.springframework.security.access.AccessDeniedException;
Import Org.springframework.security.access.ConfigAttribute;
Import Org.springframework.security.access.SecurityConfig;
Import org.springframework.security.authentication.InsufficientAuthenticationException;
Import Org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Import Org.springframework.security.authentication.dao.DaoAuthenticationProvider;
Import org.springframework.security.core.Authentication;
Import org.springframework.security.core.GrantedAuthority;
Import Org.springframework.security.core.context.SecurityContextHolder;
Import org.springframework.security.web.FilterInvocation; Import Cn.syher.common.ConstanTvalues;
Import Cn.syher.system.memcache.UserCookie;
Import Cn.syher.system.memcache.UserCookieService; public class Myaccessdecisionmanager implements Accessdecisionmanager {@Autowired private usercookieservice Usercooki
EService;
@Value ("#{configproperties[' Login.accesstoken ']}") Private String PublicKey;
@Autowired private Daoauthenticationprovider Authenticationprovider; @Override public void Decide (authentication authentication, Object object, Collection<configattribute> Configatt Ributes) throws Accessdeniedexception, insufficientauthenticationexception {if (configattributes = null) {Retu
RN; /** * Restart Tomcat, memcached has user information * But spring security does not authenticate the user so it will be an anonymous user (anonymoususer) * Therefore, when the user has permission to operate, use the Authen Tication judgment is unable to pass authorization * so need to re-authenticate the user/if (object instanceof filterinvocation && "Anonymoususer". Equals (auth
Entication.getprincipal ()) {filterinvocation fi = (filterinvocation) object; Securityuser user = (securityUser) Fi.getrequest (). GetSession (). getattribute (constantvalues.login_user_session); if (user = = null) {//from memcached Usercookie Usercookie = Usercookieservice.getusercookiefromsystem (
Fi.gethttprequest (), Fi.getresponse (), PublicKey);
user = (usercookie==null)? Null:userCookie.getUser (); } if (user!= null) {//re-certified, remember to use plaintext password Authentication request = new Usernamepasswordauthenticationtoken (user.getaccount
(), User.getpwdshow ()/*user.getpassword () * *);
authentication = authenticationprovider.authenticate (request);
Securitycontextholder.getcontext (). Setauthentication (authentication);
} iterator<configattribute> ite = Configattributes.iterator ();
while (Ite.hasnext ()) {Configattribute CA = Ite.next ();
String Needrole = ((securityconfig) CA). getattribute ();
For (grantedauthority ga:authentication.getAuthorities ()) {if (Needrole.trim (). Equals (Ga.getauthority (). Trim ())) {
Return }} throw new Accessdeniedexception ("No permissions.");
@Override public Boolean supports (Configattribute attribute) {return true;
@Override public Boolean supports (Class<?> clazz) {return true;
}
}
Security.xml
<pre name= "code" class= "HTML" ><b:bean id= "Accessdecisionmanager" Cn.syher.system.security.MyAccessDecisionManager "></b:bean>
<b:bean id=" Myfilter "class=" Org.springframework.security.web.access.intercept.FilterSecurityInterceptor ">
<b:property name=" AuthenticationManager "
ref=" AuthenticationManager "/> <b:property name=" Accessdecisionmanager "
ref= "Accessdecisionmanager"/>
<b:property name= "Securitymetadatasource"
Securitymetadatasource "/>
</b:bean>
So far, the problem is solved.
Do not know whether there is a better way, some words are welcome to inform.