Spring Security + memcached restart Tomcat Anonymous (anonymoususer) problem

Source: Internet
Author: User
Tags auth memcached object object

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.

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.