Part III: Shiro Integration Spring uses CAS single sign-on configuration __cas

Source: Internet
Author: User
Tags aop cas ticket
Part III Shiro Integrated spring uses CAS single sign-on configuration (i) Shiro single sign-on

The main purpose of the configuration is to change the login page to ${cas.server}?service=${cas.client}/login form, followed by the local callback address. After the CAS server-side login succeeds, ticket is generated to return to the client, and the client's Shiro is saved with ticket most credentials.
  
Shiro configuration after the single point of login, the original cas-client can only delete the httpsession, can not delete the Shiro session, so did not use the Shiro session manager.
If you want to enable Shiro Session Manager, you can refer to the Shiro & CAS implementation single sign-on.
The original Casrealm only saves the user name in AuthenticationInfo as the Principal,mycasrealm overrides this method and saves the user information class instead.
Need to increase dependency on Pom, Shiro-cas will automatically increase cas-client-core-3.2.1 dependency via dependent delivery.

<!--Shiro-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    < artifactid>shiro-spring</artifactid>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactid>shiro-cas </artifactId>
    <version>1.2.3</version>
</dependency>
1, spring-shiro.xml configuration
<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:util= "Http://www.springframework.org/schema/util" Xmlns:ao p= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:context= "Http://www.springframework.org/schema/context" xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans.xsd Http://www.springframework.org/schema/util http://www.springframework.org/schema/util/ Spring-util.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ Spring-aop.xsd Http://www.springframework.org/schema/context http://www.springframework.org/schema/context/ Spring-context.xsd "default-lazy-init=" false "> <description>shiro Security Configuration </description> <!--slow The Save manager--> <bean id= "CacheManager class=" Com.whty.framework.base.common.cache.Springcachemanagerwrapper "> <property name=" CacheManager "ref=" Springcachemanager "/> </bean> <!--Realm implementation--> <bean id= "Casrealm" class= "Com.whty.oim.base.shiro.MyCasRealm" > <property n
        Ame= "cachingenabled" value= "true"/> <property name= "authenticationcachingenabled" value= "true"/> <property name= "Authenticationcachename" value= "Authenticationcache"/> <property name= "AuthorizationCachi" Ngenabled "value=" true "/> <property name=" authorizationcachename "value=" Authorizationcache "/> &L t;! --CAS Server--> <property name= "Casserverurlprefix" value= "${cas.server}"/> <!--client's callback address settings, 

    The address that must be intercepted with the following Shiro-cas filter--> <property name= "Casservice" value= "${cas.client}/login"/> </bean> <bean id= "Cassubjectfactory" class= "Org.apache.shiro.cas.CasSubjectFactory"/> <!--security Manager--> ; Bean id= "SecuritymanAger "class=" Org.apache.shiro.web.mgt.DefaultWebSecurityManager "> <property name=" Realm "ref=" Casrealm "/>" <!--<property name= "SessionManager" ref= "SessionManager"/>--> <property name= "CacheManag" Er "ref=" CacheManager/> <!--sessionmode parameter is set to native, then Shrio saves the user's Basic authentication information to a CA with the default name called Shiro-activesessioncache Che zhong--> <!--<property name= "SessionMode value=" native "/>--> <property name=" SUBJECTFA Ctory "ref=" cassubjectfactory/> </bean> <!--equivalent to calling Securityutils.setsecuritymanager (SecurityManager) --> <bean class= "Org.springframework.beans.factory.config.MethodInvokingFactoryBean" > <property na Me= "Staticmethod" value= "Org.apache.shiro.SecurityUtils.setSecurityManager"/> <property name= "arguments" ref
        = "SecurityManager"/> </bean> <bean id= "Casfilter" class= "Org.apache.shiro.cas.CasFilter" > <!--the failure page when configuring validation errors--> <property name= "failureurl" value= "${cas.client}"/> </bean> <bean id= "Shirofilter" cl ass= "Org.apache.shiro.spring.web.ShiroFilterFactoryBean" > <property name= "SecurityManager" ref= "Securityman" Ager "/> <!--set the login link for the role, where the link to the CAS login page can be configured with callback address--> <property name=" loginurl "value=" ${cas.serve R}?service=${cas.client}/login "/> <property name= successurl" value= "/index"/> <property nam E= "Unauthorizedurl" value= "/"/> <property name= "Filters" > <util:map> & lt;! --<entry key= "authc" value-ref= "Authcfilter"/> <entry key= "Captchafilter" value-ref= "CaptchaFilt" Er "/>--> <!--add Casfilter to Shirofilter--> <entry key=" cas "value-ref=" casf 
            Ilter "/> </util:map> </property> <property name=" Filterchaindefinitions "> <value>/logout = Logout/login = cas/** = user </value> < /property> </bean> <!--guarantee the implementation of the Shiro internal lifecycle function of the bean execution--> <bean id= "Lifecyclebeanpostproce Ssor "class=" Org.apache.shiro.spring.LifecycleBeanPostProcessor "/> </beans>
2, Cas.properties

Cas.server=http://192.168.5.129:8080/cas
Cas.client=http://192.168.4.184:8091/ucs 3, custom realm implementation

The main modification of the Casrealm Dogetauthenticationinfo () method, Casrealm the default only to save the username, the system to save the Shirouser object.

public class Mycasrealm extends Casrealm {Logger Logger = Loggerfactory.getlogger (Mycasrealm.class);

    @Autowired private Ucsuserservice Ucsuserservice;

    @Autowired private Ucsroleservice Ucsroleservice;

    @Autowired private Ucspermissionservice Ucspermissionservice;

    @Value ("${domain}") private String domain;
     /** * Authorization Query callback function, which is invoked when there is no user authorization information in the cache. * * @see Org.apache.shiro.realm.authorizingrealm#dogetauthorizationinfo ( org.apache.shiro.subject.PrincipalCollection) * * * * @Override protected Authorizationinfo Dogetauthorizationinfo (PrincipalCollection principals)
        {Shirouser Shirouser = (shirouser) principals.getprimaryprincipal ();
        Ucsuser Ucsuser = Ucsuserservice.selectbyusername (shirouser.loginname); Put principals in session Key=userid Value=principals Securityutils.getsubject () getsession (). setattribute (String.va
        Lueof (Ucsuser.getid ()), Securityutils.getsubject (). Getprincipals ()); SimpLeauthorizationinfo info = new Simpleauthorizationinfo ();
        Assign role list<ucsrole> ucsroles = Ucsroleservice.selectbyuser (Ucsuser.getid ()); if (! Checkemptyutil.isempty (Ucsroles)) {for (Ucsrole ucsrole:ucsroles) {info.addrole (Ucsrole.getid ()
            ); }//Assign permissions//list<ucspermission> ucspermissions = Ucspermissionservice.selectbyuser (ucsuser.
        GetId (), domain); if (!
                Checkemptyutil.isempty (Shirouser.getmenus ())) {for (Easyuimenu Permission:shiroUser.getMenus ()) { if (UcsBaseConstant.PermissionType.BUTTON.equals (Permission.gettype ())) Info.addstringpermission (Permissi
            On.geturl ());
    } return info;
     }/** * Authenticates a user and retrieves its information. * * @param token the authentication token * @throws Authenticationexception if there is a error during authent
     Ication.
    * * @OverrideProtected AuthenticationInfo Dogetauthenticationinfo (Authenticationtoken token) throws Authenticationexception {C
        Astoken Castoken = (castoken) token;
        if (token = = null) {return null;
        String ticket = (string) castoken.getcredentials (); if (!
        Stringutils.hastext (Ticket)) {return null;

        } ticketvalidator Ticketvalidator = Ensureticketvalidator (); try {//Contacts CAS server to validate service ticket assertion casassertion = Ticketvalidator.va
            Lidate (Ticket, Getcasservice ());
            Get principal, User ID and attributes Attributeprincipal casprincipal = Casassertion.getprincipal ();
            String username = casprincipal.getname (); Logger.debug ("Validate ticket: {} in CAS server: {} to retrieve user: {}", new object[]{ticket, GE

            Tcasserverurlprefix (), username}); map<string, object> attRibutes = Casprincipal.getattributes ();
            Refresh Authentication token (User ID + remember me) Castoken.setuserid (username);
            String remembermeattributename = Getremembermeattributename ();
            String remembermestringvalue = (string) attributes.get (remembermeattributename);
            Boolean isremembered = Remembermestringvalue!= null && boolean.parseboolean (remembermestringvalue);
            if (isremembered) {castoken.setrememberme (true); //Create simple Authentication info//user name to get account information ucsuser Ucsuser = Ucsuserservice
            . Selectbyusername (username);
            List<ucspermission> ucspermissions = null;
            if (Ucsuser!= null) {ucspermissions = Ucspermissionservice.selectbyuser (Ucsuser.getid (), domain); else {throw new unknownaccountexception ();//Login Failed}//To menu sort L Ist&lT
            easyuimenu> menus = toeasyuimenu (ucspermissions); if (!
            Checkemptyutil.isempty (Menus)) {collections.sort (menus);

            } shirouser Shirouser = new Shirouser (Ucsuser.getid (), Ucsuser.getusername (), ucsuser.getname (), menus);
        return new Simpleauthenticationinfo (Shirouser, Ticket, GetName ()); catch (Ticketvalidationexception e) {throw new Casauthenticationexception ("Unable to validate ticket [" +
        Ticket + "]", e); } private list<easyuimenu> Toeasyuimenu (list<ucspermission> ucspermissions) {List<easyui
        menu> menus = new arraylist<easyuimenu> (0);
        for (Ucspermission ucspermission:ucspermissions) {Menus.add (Toeasyuimenu (ucspermission));
    return menus; Private Easyuimenu Toeasyuimenu (ucspermission ucspermission) {return new Easyuimenu (Ucspermission.getid (), U Cspermission.getpid (), Ucspermission.getdomaiN (), Ucspermission.getname (), Ucspermission.gettype (), Ucspermission.getsort (), Ucspermission.geticon (),
    Ucspermission.geturl (), Ucspermission.getdescription (), Ucspermission.getstatus ()); @Override public void Clearcachedauthorizationinfo (PrincipalCollection principals) {Super.clearcacheda
    Uthorizationinfo (principals); @Override public void Clearcachedauthenticationinfo (PrincipalCollection principals) {super.clearcached
    AuthenticationInfo (principals);
        @Override public void ClearCache (PrincipalCollection principals) {Super.clearcache (principals);
    Clearallcache ();
    public void Clearallcachedauthorizationinfo () {Getauthorizationcache (). Clear ();
    public void Clearallcachedauthenticationinfo () {Getauthenticationcache (). Clear ();
        public void Clearallcache () {clearallcachedauthenticationinfo ();
    Clearallcachedauthorizationinfo (); }

}
(b) CAs log out

  
After any subsystem is logged out, the CAS server sends a logout request to all subsystems that have sent a login request to disable the httpsession of all subsystems. If you use the Shiro Session Manager, you need to modify the CAS client code to remove the Shiro session when removing httpsession. 1, Web.xml

In Web.xml, the singlesignoutfilter of CAS is required to implement a single point of logout, which needs to be placed before Shirofilter, after the spring character set filter. When used in practice, it is found that the data is garbled in the process of transmission if it is placed before the spring character set filter (Singlesignoutfilter).

The <!--is used for single point exit, which is used to implement single point logout and optional configuration. -->
<listener>
    <listener-class> Org.jasig.cas.client.session.singlesignouthttpsessionlistener</listener-class>
</listener>
<!--The filter is used for single point logout and optional configuration. -->
<filter>
    <filter-name>cas single Sign out filter</filter-name>
    < filter-class>org.jasig.cas.client.session.singlesignoutfilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cas single Sign out filter</filter-name>
    <url-pattern >/*</url-pattern>
</filter-mapping>
2. Log Out Request

Log out only need to jump the current page to the CAS server logout page to achieve logout. If you need to log in after the jump page, you can add service parameters and refer to section Fourth of the first section for configuration.
The subsystem uses the method to assemble the logout link in the background, send it to the front page, and the foreground page accepts using El expressions. Specific implementations need to be implemented on a per-subsystem basis.

@Value ("${cas.server}")
private String cas_server;  
@Value ("${cas.client}")
private String cas_client;

@RequestMapping (value = "/index") public
String index (model model) {
    StringBuilder logouturl = new StringBuilder ();
    Logouturl.append (cas_server);
    Logouturl.append ("/logout?service=");
    Logouturl.append (cas_client);
    Model.addattribute ("Logouturl", logouturl.tostring ());
    return "System/index";
}

Front page:

<script>
    var logouturl = ' ${logouturl} ';
</script>
cache configuration (optional)

I use the Ehcache as a Shiro cache, and I can use the other.
Spring-cache.xml

<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "Http://www.springframework.org/schema/aop" xmlns: context= "Http://www.springframework.org/schema/context" xmlns:jdbc= "Http://www.springframework.org/schema/jdbc" xmlns:tx= "Http://www.springframework.org/schema/tx" xsi:schemalocation= "http://www.springframework.org/schema/ Beans Http://www.springframework.org/schema/beans/spring-beans.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http ://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http:// Www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http:// Www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http:// Www.springframework.org/schema/tx/spring-tx.xsd "default-lazy-init=" false "> <bean id="Springcachemanager "class=" Org.springframework.cache.ehcache.EhCacheCacheManager "> <property name=" Cacheman Ager "ref=" Ehcachemanager "/> </bean> <!--ehcache--> <bean id=" Ehcachemanager "class=" org.sp Ringframework.cache.ehcache.EhCacheManagerFactoryBean "> <property name=" configlocation "value=" CLASSPATH:PR Operties/ehcache.xml "/> </bean> </beans>

Ehcache.xml

<?xml version= "1.0" encoding= "UTF-8"?> <ehcache xmlns:xsi=  
"HTTP://WW"

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.