cas+SpringSecurity注解方式(五)

5.1SpringSecurity搭建
5.1.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>springsecurity-cas-annotation-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--war包-->
    <packaging>war</packaging>

    <dependencies>
        <!--spring-security-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>

        <!--集成包-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-cas</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>

        <!--cas核心包-->
        <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>3.3.3</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--日志包-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!--servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

5.1.2 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!--指定spring配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <!--spring監(jiān)聽-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--委托過濾器:springSecurityFilterChain-->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

5.1.3 spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--包掃描-->
    <context:component-scan base-package="org.example" />

</beans>

5.1.4 創(chuàng)建自定義授權認證類

@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    /***
     * 自定義認證授權
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String password="123456";

        //角色信息
        List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

        return new User(username,password,grantedAuthorities);
    }
}

5.1.5 創(chuàng)建SpringSecur配置類
配置類需要注意加上@Component淮菠、@EnableWebSecurity注解采郎,同時注解3個方法分別為忽略某些地址的安全校驗祟牲、設置需要攔截過濾的地址的安全校驗規(guī)則、設置授權認證器三個方法都是configure方法起意。代碼如下:

@Component
@EnableWebSecurity
public class SpringSecurityCOnfig extends WebSecurityConfigurerAdapter {

    /***
     * 三個configure方法
     * 1)忽略某些地址的安全校驗
     * 2)設置需要攔截過濾的地址的安全校驗規(guī)則
     * 3)設置授權認證器
     */


    /***
     * 1)忽略某些地址的安全校驗
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/image/**");
        web.ignoring().antMatchers("/403.html");
    }

    /***
     * 2)設置需要攔截過濾的地址的安全校驗規(guī)則
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //除了上面忽略安全校驗的地址,其他的一律需要ROLE_ADMIN角色權限訪問
        http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");

        //允許iframe的使用
        http.headers().frameOptions().disable();

        //禁止csrf
        http.csrf().disable();

        //開啟登錄功能
        http.formLogin();

        //開啟登出功能
        http.logout();

        //異常處理
        http.exceptionHandling().accessDeniedPage("/403.html");
    }

    /***
     * 注入自定義授權認證類
     */
    @Autowired
    private UserDetailsService userDetailsService;

    /***
     * 3)設置授權認證器
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
}
5.1.6 新建資源文件

創(chuàng)建image,并拷貝1.jpg進去病瞳,作為開放資源揽咕。創(chuàng)建jsp/1.jsp悲酷,作為權限控制目錄。創(chuàng)建403亲善,作為無權訪問的頁面设易。

image.jpg

5.2 集成CAS

5.2.1 創(chuàng)建cas.properties

這里面記錄了cas相關的訪問地址以及自身相關的訪問地址

#CAS服務地址
cas.server.host.url=http://localhost:28083/cas
#CAS服務登錄地址
cas.server.host.login_url=http://localhost:28083/cas/login
#CAS服務登出地址
cas.server.host.logout_url=http://localhost:28083/cas/logout?service=http://localhost:28086
#應用訪問地址
app.server.host.url=http://localhost:28086
#應用登錄地址
app.login.url=/login
#應用登出地址
app.logout.url=/logout

5.2.2 創(chuàng)建CasProperties.java配置類
該類的作用是用于讀取上面的配置文件

@Component
public class CasProperties {
    @Value("${cas.server.host.url}")
    private String casServerUrl;

    @Value("${cas.server.host.login_url}")
    private String casServerLoginUrl;

    @Value("${cas.server.host.logout_url}")
    private String casServerLogoutUrl;

    @Value("${app.server.host.url}")
    private String appServerUrl;

    @Value("${app.login.url}")
    private String appLoginUrl;

    @Value("${app.logout.url}")
    private String appLogoutUrl;

    //get...set...
}

5.2.3 集成CAS認證和相關過濾器
修改configure方法,代碼如下蛹头,分別加入了自定義授權認證類和Cas過濾器以及登出配置顿肺。我們需要將之前的用戶自定義授權認證類去掉.

/***
 * 2)設置需要攔截過濾的地址的安全校驗規(guī)則
 * @param http
 * @throws Exception
 */
@Override
protected void configure(HttpSecurity http) throws Exception {
    //除了上面忽略安全校驗的地址,其他的一律需要ROLE_ADMIN角色權限訪問
    http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");

    //允許iframe的使用
    http.headers().frameOptions().disable();

    //禁止csrf
    http.csrf().disable();

    //開啟登錄功能
    http.formLogin();

    //開啟登出功能
    http.logout();

    //異常處理
    http.exceptionHandling().accessDeniedPage("/403.html")
            .authenticationEntryPoint(casAuthenticationEntryPoint())    //設置自定義授權認證類
            .and()
            .addFilter(casAuthenticationFilter())                       //設置CAS授權過濾器
            .addFilterBefore(casLogoutFilter(),LogoutFilter.class)      //登出配置
            .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);//登出配置
}

過濾器以及授權認證類的實現(xiàn)

/***
 * UserDetailsServiceImpl在SpringIOC容器中
 */
@Autowired
private UserDetailsService userDetailsService;

//Cas認證入口
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint(){
    //用于配置Cas認證入口信息
    CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
    //設置登錄地址
    casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
    //返回的服務信息
    casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
    return  casAuthenticationEntryPoint;
}

/****
 * 服務配置信息
 * @return
 */
@Bean
public ServiceProperties serviceProperties(){
    //服務信息配置
    ServiceProperties serviceProperties = new ServiceProperties();
    //設置應用訪問信息
    serviceProperties.setService(casProperties.getAppServerUrl()+casProperties.getAppLoginUrl());
    //針對非空登錄用戶進行身份校驗
    serviceProperties.setAuthenticateAllArtifacts(true);
    return  serviceProperties;
}


/**CAS認證過濾器*/
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
    //設置CAS授權過濾器
    CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
    //集成SpringSecurity授權認證器
    casAuthenticationFilter.setAuthenticationManager(authenticationManager());
    casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
    return casAuthenticationFilter;
}

/**
 * cas 認證 Provider
 * */
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
    //創(chuàng)建CAS授權認證器
    CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
    //集成自定義授權認證器
    casAuthenticationProvider.setUserDetailsService(userDetailsService);
    //設置Cas授權認證器相關配置
    casAuthenticationProvider.setServiceProperties(serviceProperties());
    //設置票據(jù)校驗器
    casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
    casAuthenticationProvider.setKey("casAuthenticationProviderKey");
    return casAuthenticationProvider;
}

/**
 * 設置票據(jù)校驗地址-CAS地址
 * @return
 */
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
    return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
}

/**單點登出過濾器*/
@Bean
public SingleSignOutFilter singleSignOutFilter() {
    SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
    singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
    singleSignOutFilter.setIgnoreInitConfiguration(true);
    return singleSignOutFilter;
}

/**請求單點退出過濾器*/
@Bean
public LogoutFilter casLogoutFilter() {
    LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
    logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
    return logoutFilter;
}

5.2.4 完整代碼

@Component
@EnableWebSecurity      //開啟SpringSecurity注解配置
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CasProperties casProperties;

    //三個方法的方法名都是:configure

    /***
     * 1)忽略某些地址的安全校驗
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/image/**");
        web.ignoring().antMatchers("/403.html");
    }

    /***
     * 2)設置需要攔截過濾的地址的安全校驗規(guī)則
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //除了上面忽略安全校驗的地址渣蜗,其他的一律需要ROLE_ADMIN角色權限訪問
        http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");

        //允許iframe的使用
        http.headers().frameOptions().disable();

        //禁止csrf
        http.csrf().disable();

        //開啟登錄功能
        http.formLogin();

        //開啟登出功能
        http.logout();

        //異常處理
        http.exceptionHandling().accessDeniedPage("/403.html")
                .authenticationEntryPoint(casAuthenticationEntryPoint())    //設置自定義授權認證類
                .and()
                .addFilter(casAuthenticationFilter())                       //設置CAS授權過濾器
                .addFilterBefore(casLogoutFilter(),LogoutFilter.class)      //登出配置
                .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);//登出配置
    }


    /***
     * UserDetailsServiceImpl在SpringIOC容器中
     */
    @Autowired
    private UserDetailsService userDetailsService;

    //Cas認證入口
    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint(){
        //用于配置Cas認證入口信息
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        //設置登錄地址
        casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
        //返回的服務信息
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
        return  casAuthenticationEntryPoint;
    }

    /****
     * 服務配置信息
     * @return
     */
    @Bean
    public ServiceProperties serviceProperties(){
        //服務信息配置
        ServiceProperties serviceProperties = new ServiceProperties();
        //設置應用訪問信息
        serviceProperties.setService(casProperties.getAppServerUrl()+casProperties.getAppLoginUrl());
        //針對非空登錄用戶進行身份校驗
        serviceProperties.setAuthenticateAllArtifacts(true);
        return  serviceProperties;
    }


    /**CAS認證過濾器*/
    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        //設置CAS授權過濾器
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        //集成SpringSecurity授權認證器
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
        return casAuthenticationFilter;
    }

    /**
     * cas 認證 Provider
     * */
    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        //創(chuàng)建CAS授權認證器
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        //集成自定義授權認證器
        casAuthenticationProvider.setUserDetailsService(userDetailsService);
        //設置Cas授權認證器相關配置
        casAuthenticationProvider.setServiceProperties(serviceProperties());
        //設置票據(jù)校驗器
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
        casAuthenticationProvider.setKey("casAuthenticationProviderKey");
        return casAuthenticationProvider;
    }

    /**
     * 設置票據(jù)校驗地址-CAS地址
     * @return
     */
    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
    }

    /**單點登出過濾器*/
    @Bean
    public SingleSignOutFilter singleSignOutFilter() {
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
        singleSignOutFilter.setIgnoreInitConfiguration(true);
        return singleSignOutFilter;
    }

    /**請求單點退出過濾器*/
    @Bean
    public LogoutFilter casLogoutFilter() {
        LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
        logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
        return logoutFilter;
    }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末屠尊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耕拷,更是在濱河造成了極大的恐慌讼昆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斑胜,死亡現(xiàn)場離奇詭異控淡,居然都是意外死亡,警方通過查閱死者的電腦和手機止潘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門掺炭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人凭戴,你說我怎么就攤上這事涧狮。” “怎么了么夫?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵者冤,是天一觀的道長。 經常有香客問我档痪,道長涉枫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任腐螟,我火速辦了婚禮愿汰,結果婚禮上,老公的妹妹穿的比我還像新娘乐纸。我一直安慰自己衬廷,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布汽绢。 她就那樣靜靜地躺著吗跋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跌宛,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天酗宋,我揣著相機與錄音,去河邊找鬼秩冈。 笑死本缠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的入问。 我是一名探鬼主播丹锹,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼芬失!你這毒婦竟也來了楣黍?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤棱烂,失蹤者是張志新(化名)和其女友劉穎租漂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颊糜,經...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哩治,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衬鱼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片业筏。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鸟赫,靈堂內的尸體忽然破棺而出蒜胖,到底是詐尸還是另有隱情,我是刑警寧澤抛蚤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布台谢,位于F島的核電站,受9級特大地震影響岁经,放射性物質發(fā)生泄漏朋沮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一缀壤、第九天 我趴在偏房一處隱蔽的房頂上張望朽们。 院中可真熱鬧,春花似錦诉位、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啤誊,卻和暖如春岳瞭,著一層夾襖步出監(jiān)牢的瞬間拥娄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工瞳筏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稚瘾,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓姚炕,卻偏偏與公主長得像摊欠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柱宦,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348