Spring boot + Shiro + Swagger基本登錄相關(guān)配置(一)

一宪摧、相關(guān)框架簡(jiǎn)介
1.1 spring boot
spring boot是由Pivotal團(tuán)隊(duì)開發(fā)的全新框架谈截,其主要目的是使搭建spring web項(xiàng)目變得簡(jiǎn)單违帆、快速挣磨,能快速進(jìn)入到項(xiàng)目的業(yè)務(wù)邏輯開發(fā)。其主要的配置是在application命名的文件中劣摇,主要有application.properties和application.yml兩種配置方式珠移,spring boot項(xiàng)目啟動(dòng)時(shí)會(huì)默認(rèn)到項(xiàng)目路徑下去尋找application的文件并讀取內(nèi)容。
1.2 Shiro
Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證末融、授權(quán)钧惧、密碼學(xué)和會(huì)話管理。shiro主要由三個(gè)主要組建組成:Subject(當(dāng)前操作用戶勾习,不僅僅是人或事物的對(duì)象垢乙,還可能是線程),SecurityManager(shiro的核心框架语卤,用來(lái)管理內(nèi)部組建實(shí)例并提供安全管理的服務(wù)),Realm(是shiro和安全數(shù)據(jù)數(shù)據(jù)的橋梁,當(dāng)對(duì)用戶進(jìn)行授權(quán)或身份驗(yàn)證時(shí)粹舵,shiro會(huì)從配置的Realm中查找用戶和其相關(guān)權(quán)限)钮孵。Realm相當(dāng)于我們開發(fā)過(guò)程中的dao層,它封裝了數(shù)據(jù)連接的細(xì)節(jié)眼滤。
1.3 Swagger
swagger是目前最受歡迎的Rest Apis文檔生成工具之一巴席,它可以生成支持互動(dòng)類型的API控制臺(tái),生成可以在不能平臺(tái)運(yùn)行的客戶端SDK诅需,Swagger 文檔提供了一個(gè)方法漾唉,使我們可以用指定的 JSON 或者 YAML 摘要來(lái)描述你的 API,包括了比如 names堰塌、order 等 API 信息等優(yōu)點(diǎn)赵刑。
二、基本接口的提供
以u(píng)ser為列场刑,提供相關(guān)接口般此,具體實(shí)現(xiàn)忽略。controller代碼如下:

package com.why.greenhouse.back.user.controller;

import com.why.greenhouse.back.config.filter.ShiroProperties;
import com.why.greenhouse.back.user.entity.User;
import com.why.greenhouse.back.user.service.UserService;
import com.why.greenhouse.back.user.model.request.UserRequest;
import com.why.greenhouse.back.user.model.response.UserResponse;

import java.util.List;
import java.util.Map;

import com.why.greenhouse.back.utils.UserUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 描述:user控制層
 *
 * @author why
 * @date 2018-07-07 14:17:51
 */
@RestController
@RequestMapping(path = "user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 描述:根據(jù)Id 查詢
     *
     * @param id userid
     */
    @GetMapping("findById")
    public UserResponse findById(@RequestParam("id") Long id) throws Exception {
        UserResponse userResponse = userService.queryUserById(id);
        return userResponse;
    }

    /**
     * 描述:創(chuàng)建user
     *
     * @param userRequest
     */
    @PostMapping("add")
    public void add(@RequestBody UserRequest userRequest) throws Exception {
        userService.addUser(userRequest);
    }

    /**
     * 描述:刪除user
     *
     * @param id userid
     */
    @DeleteMapping("deleteById")
    public void deleteById(@RequestParam("id") Long id) throws Exception {
        userService.deleteUser(id);
    }

    /**
     * 描述:更新user
     *
     * @param userRequest userRequest
     */
    @PostMapping("update")
    public void update(@RequestBody UserRequest userRequest) throws Exception {
        userService.updateUser(userRequest);
    }
    @Autowired
    private ShiroProperties shiroProperties;
    /**
     * 描述:查詢所有user
     */
    @PostMapping("queryAll")
    public List<UserResponse> queryAll() throws Exception {
        for(String s : shiroProperties.getFilterRules()){
            System.out.println(s);
        }
        return userService.queryAll();
    }
    /**
     * 描述:查詢所有user
     */
    @GetMapping("login")
    public void login(){
//    public void login(@RequestParam(name = "name") String name){
//        User user = userService.queryByName(name);
//        if (user==null){
//            throw new RuntimeException("不存在改用戶");
//        }
        System.out.println("的點(diǎn)點(diǎn)滴滴多多多");
    }
}

三牵现、shiro Filter相關(guān)代碼
添加相關(guān)依賴,依賴中有一些自己測(cè)試用的包铐懊,該功能沒有用到

<?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.why</groupId>
   <artifactId>greenhouse</artifactId>
   <packaging>pom</packaging>
   <version>1.0-SNAPSHOT</version>
   <modules>
       <module>common</module>
       <module>front</module>
       <module>back</module>
       <module>core</module>
   </modules>
   <name>Green House Server</name>
   <description>Green House Server</description>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.3.RELEASE</version>
   </parent>
   <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
       <java.version>1.8</java.version>
       <swagger.version>2.7.0</swagger.version>
   </properties>
   <dependencies>
       <!-- jpa -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-data-jpa</artifactId>
       </dependency>
       <!--cache-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-cache</artifactId>
       </dependency>
       <!--lombok依賴-->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.16.18</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!-- aop -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-aop</artifactId>
       </dependency>
       <!-- the follow depends is for junit test and api test -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
       <!-- 數(shù)據(jù)庫(kù)MySQL -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.21</version>
       </dependency>
       <dependency>
           <groupId>io.springfox</groupId>
           <artifactId>springfox-swagger2</artifactId>
           <version>${swagger.version}</version>
           <exclusions>
               <exclusion>
                   <artifactId>reflections</artifactId>
                   <groupId>org.reflections</groupId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>io.springfox</groupId>
           <artifactId>springfox-swagger-ui</artifactId>
           <version>${swagger.version}</version>
       </dependency>
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>fastjson</artifactId>
           <version>1.2.16</version>
       </dependency>

       <!-- shiro -->
       <dependency>
           <groupId>org.apache.shiro</groupId>
           <artifactId>shiro-all</artifactId>
           <version>1.2.5</version>
       </dependency>

       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid</artifactId>
           <version>RELEASE</version>
       </dependency>
       <dependency>
           <groupId>org.apache.shiro</groupId>
           <artifactId>shiro-spring</artifactId>
           <version>1.4.0</version>
       </dependency>
   </dependencies>
</project>

通過(guò)@Bean方式注入自己定義的攔截和shiro相關(guān)的類

package com.why.greenhouse.back.config.filter;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author why
 * 攔截器實(shí)例化
 */
@Configuration
@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
public class LoginFilterBean{
    @Autowired
    private ShiroProperties shiroProperties;
    @Bean
    public LoginFilter loginFilter(){
        return new LoginFilter();
    }
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        return securityManager;
    }

    @ConditionalOnMissingBean
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
        //打印日志便于查看是否進(jìn)入該攔截器
        System.out.println("LoginFilterBean.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        Map<String,Filter> filterMap = new HashMap<>(20);
        //定義攔截器名稱
        filterMap.put("hasToken",new LoginFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> filterChainMap = new HashMap<>(20);
        //從配置文件中自定義攔截規(guī)則的相關(guān)配置信息
        List<String> filters = shiroProperties.getFilterRules();
        if (null!=filters){
            for (String str: filters) {
                String[] temp = str.split("==>");
                if (temp.length != 2) {
                    throw new IllegalStateException("過(guò)濾規(guī)則配置不正確,格式:url==>filters");
                }
                filterChainMap.put(temp[0],temp[1]);
            }
        }
        //把自己定義的攔截相關(guān)規(guī)則交給shiro管理
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        shiroFilterFactoryBean.setSuccessUrl("/");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        return shiroFilterFactoryBean;
    }

    /**
     * 加入注解的使用,不加入這個(gè)注解不生效
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

application.yml文件相關(guān)配置信息如下:

server:
  tomcat:
    uri-encoding: UTF-8
    max-threads: 3000
  port: 15030
  compression:
    enabled: true
spring:
  datasource:
    password: 1pTVg0ld@1909
    tomcat:
      max-idle: 10
      min-idle: 5
      test-on-borrow: false
      test-while-idle: true
      time-between-eviction-runs-millis: 18800
      validation-query: SELECT 1
      initial-size: 5
      max-wait: 3000
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/why?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOver
    username: root
    hikari:
      read-only:
  messages:
    cache-seconds: -1
    always-use-message-format: false
    fallback-to-system-locale: true
    basename: i18n/messages
    encoding: UTF-8
  jpa:
    show-sql: true
    database: MYSQL
    generate-ddl: false
    hibernate:
      ddl-auto: update
    properties:
      globally_quoted_identifiers: true
      use_query_cache: false
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
shiro:
    filter-rules:
        - /swagger-ui.html==>anon
        - /swagger-resources/**==>anon
        - //webjars/**==>anon
        - /v2/**==>anon
        - /user/login/**==>anon
        - /user/queryAll/**==>anon
        - /**==>authc

這個(gè)時(shí)候還訪問不了swagger頁(yè)面瞎疼,需要對(duì)swagger進(jìn)行相關(guān)的配置科乎,配置類如下:

package com.why.greenhouse.back.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * swagger配置
 * @author why
 */
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
    @Bean
    public Docket createRestApi(){
        //add head start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        tokenPar.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());
        //add head end
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.why.greenhouse"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars);
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("GREEN TOKEN SERVER API information")
                .description("GREEN TOKEN SERVER API information")
                .version("1.0")
                .build();
    }
}

四、代碼演示及相關(guān)問題修改
這個(gè)時(shí)候我們?cè)L問http://localhost:15030/swagger-ui.html時(shí)出現(xiàn)如下情況:

image.png

我們的接口沒有了贼急,再看看請(qǐng)求
image.png

和后臺(tái)日志
image.png

顯然是我們請(qǐng)求swagger頁(yè)面的時(shí)候有的頁(yè)面被攔截器攔截住了茅茂,通過(guò)請(qǐng)求地址可以看出是在/swagger-resources/configuration請(qǐng)求后跳轉(zhuǎn)到我們攔截之后的接口的,因此對(duì)application.yml文件的配置做了如下修改
其中:

  - /swagger-resources/**==>anon

改成

  - /swagger-resources/**/**==>anon

修改之后重新啟動(dòng)項(xiàng)目


image.png

我們的接口出來(lái)了竿裂,

  • /user/queryAll/**==>anon調(diào)用不需要驗(yàn)證的接口:


    image.png

可以查到內(nèi)容玉吁,再查看需要登錄的接口:
后臺(tái)打印

的點(diǎn)點(diǎn)滴滴多多多

說(shuō)明進(jìn)入了我們的攔截指定的接口
五、結(jié)束
本項(xiàng)目完全為測(cè)試所用腻异,接口沒有實(shí)際意義进副,本文只是對(duì)shiro Filter做最基本的簡(jiǎn)單的登錄功能驗(yàn)證。踩完后面的坑再寫個(gè)稍微深入一點(diǎn)的悔常。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末影斑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子机打,更是在濱河造成了極大的恐慌矫户,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件残邀,死亡現(xiàn)場(chǎng)離奇詭異皆辽,居然都是意外死亡柑蛇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門驱闷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)耻台,“玉大人,你說(shuō)我怎么就攤上這事空另∨璧ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵扼菠,是天一觀的道長(zhǎng)摄杂。 經(jīng)常有香客問我,道長(zhǎng)循榆,這世上最難降的妖魔是什么析恢? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮冯痢,結(jié)果婚禮上氮昧,老公的妹妹穿的比我還像新娘。我一直安慰自己浦楣,他們只是感情好袖肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著振劳,像睡著了一般椎组。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上历恐,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天寸癌,我揣著相機(jī)與錄音,去河邊找鬼弱贼。 笑死蒸苇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吮旅。 我是一名探鬼主播溪烤,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼庇勃!你這毒婦竟也來(lái)了檬嘀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤责嚷,失蹤者是張志新(化名)和其女友劉穎鸳兽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罕拂,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揍异,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年全陨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒿秦。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烤镐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棍鳖,到底是詐尸還是另有隱情,我是刑警寧澤碗旅,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布渡处,位于F島的核電站,受9級(jí)特大地震影響祟辟,放射性物質(zhì)發(fā)生泄漏医瘫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一旧困、第九天 我趴在偏房一處隱蔽的房頂上張望醇份。 院中可真熱鬧,春花似錦循诉、人聲如沸傅联。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)怖竭。三九已至,卻和暖如春陡蝇,著一層夾襖步出監(jiān)牢的瞬間痊臭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工登夫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留广匙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓恼策,卻偏偏與公主長(zhǎng)得像鸦致,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子戏蔑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蹋凝,服務(wù)發(fā)現(xiàn),斷路器总棵,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,809評(píng)論 6 342
  • 簡(jiǎn)單來(lái)說(shuō)鳍寂,最近壓力挺大。一部分同事即將去了新公司情龄,朝夕相處了許久迄汛,也算是有一定的感情了捍壤,月末,分崩離析鞍爱。 為自己的...
    三月禿禿閱讀 178評(píng)論 0 0
  • 逃逸逃逸前: self.imageView.snp.makeConstraints({ (make) in...
    AZander閱讀 183評(píng)論 0 0
  • 最近讀了張愛玲的《傾城之戀》和《紅玫瑰和白玫瑰》這兩本小說(shuō)集鹃觉。 怎么說(shuō)呢,從剛開始帶著對(duì)經(jīng)典的尊重睹逃,到后來(lái)抱著看故...
    cy49閱讀 209評(píng)論 0 0