springboot系列十五 security 簡單配置 保護接口安全

springsecurity提供了基於用戶、角色、權限的安全控制css

簡單使用

在項目中加入security的依賴html

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

寫一個接口java

@RestController
public class IndexResource {

    @RequestMapping({"", "/", "/index"})
    public String index(){
        return "index";
    }
}

啓動項目後,訪問 localhost:8080 發現須要輸入用戶名密碼。這實際上是springsecurity的默認安全配置。web

其實日誌中已經有提示給咱們:spring

2019-01-03 13:58:55.572  INFO 79013 --- [  restartedMain] .s.s.UserDetailsServiceAutoConfiguration : 

Using generated security password: de5cf28a-25d9-47d6-a0bd-bb4e41cf4d39

這段日誌是從UserDetailsServiceAutoConfiguration這個類中打印的。npm

private String getOrDeducePassword(User user, PasswordEncoder encoder) {
        String password = user.getPassword();
        if (user.isPasswordGenerated()) {
            logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));
        }

        return encoder == null && !PASSWORD_ALGORITHM_PATTERN.matcher(password).matches() ? "{noop}" + password : password;
    }

密碼有了,那用戶名呢?bootstrap

查看security的配置類org.springframework.boot.autoconfigure.security.SecurityProperties.User,發現用戶名默認爲user,密碼是臨時UUID瀏覽器

public static class User {
        private String name = "user";//用戶名
        private String password = UUID.randomUUID().toString();//密碼
        private List<String> roles = new ArrayList();
        private boolean passwordGenerated = true;

        public User() {
        }
        //...
}

而後在瀏覽器輸入用戶名密碼,接口正常訪問緩存

自定義用戶名密碼配置

怎麼自定義用戶密碼?安全

在配置文件中加入security的配置:

spring:
  security:
    user:
      name: admin
      password: admin

而後從新訪問,輸入admin / admin 訪問成功。(部分瀏覽器須要清除以前的緩存纔看到效果)

web頁面安全訪問

在web頁面中通常都須要登陸後(拿到session)才能訪問

頁面

先寫2個頁面

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
    <title>Spring Security 登陸 </title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<form class="form-horizontal" th:action="@{/login}" method="post">
    <h1>Login</h1>
    <div th:if="${param.error}">
        用戶名或密碼錯
    </div>
    <div th:if="${param.logout}">
        您已註銷成功
    </div>
    <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">Username</label>
        <div class="col-sm-10">
            <input type="text" class="form-control" id="inputEmail3" name="username" placeholder="Username">
        </div>
    </div>
    <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
        <div class="col-sm-10">
            <input type="password" class="form-control" id="inputPassword3" name="password" placeholder="Password">
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-default">Sign in</button>
        </div>
    </div>
</form>
</body>
</html>

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
    <title>Spring Security入門</title>
</head>
<body>
<h1>歡迎使用Spring Security!</h1>

歡迎你:<p th:text="${username}"/></p>
<p>點擊 <a th:href="@{/loginout}">這裏</a> 退出登陸</p>
</body>
</html>

當用戶登陸成功後跳轉到index頁面

安全配置

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * http訪問控制
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/login").permitAll()//容許訪問
                .anyRequest().authenticated()//其餘全部url都須要鑑權,若是未登錄則跳轉登錄頁面
            .and()
                .formLogin()
                    .loginPage("/login")//指定登陸頁面地
                    .loginProcessingUrl("/login")//登陸處理url
                    .successForwardUrl("/home")//登陸成功後跳轉url
                    .permitAll()//容許訪問
            .and()
                .logout().logoutUrl("/loginout").permitAll();//指定登出url,而且容許訪問
    }

    /**
     * 全局配置:
     *  建立一個內存用戶
     *    用戶名 admin
     *    密碼 admin
     *    角色 USER
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		//新版本security框架這裏須要指定密碼加密方式,否則報錯:There is no PasswordEncoder mapped for the id 「null」
        BCryptPasswordEncoder pwdEncoder = new BCryptPasswordEncoder();
        auth.inMemoryAuthentication()
                .passwordEncoder(pwdEncoder)
                .withUser("admin")
                .password(pwdEncoder.encode("admin"))
                .roles("ADMIN");
    }
}

控制層

@RequestMapping("/login")
    public String login(){
        return "login";
    }

    @RequestMapping("/home")
    public String home(Model model){
        User principal = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        model.addAttribute("username", principal.getUsername());
        return "index";
    }

    @RequestMapping("/loginout")
    public String loginout(){
        SecurityContextHolder.clearContext();
        return "login";
    }

測試

相關文章
相關標籤/搜索