美文网首页
springboot 学习笔记(二)SpringBoot + S

springboot 学习笔记(二)SpringBoot + S

作者: 囝囝123 | 来源:发表于2019-07-30 18:17 被阅读0次

1.创建一个springboot 的demo
我使用的是Eclipse 创建的项目 springboot 版本 2.16


创建项目.png

2.添加数据源
pom 文件

<!-- 使用阿里巴巴的数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

将application.properties 改为 application.yml 并添加数据库配置

#端口号
server:
  port: 80
#数据库连接
spring:
    datasource:
        name: demotest
        url: jdbc:mysql://localhost:3306/demotest?serverTimezone=UTC
        username: root
        password: root
        # 使用druid数据源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20

3.访问 http://localhost:80

login.png
密码会打印出来
image.png
登录一下
image.png
4.使用自定义的登录页面
新建SecurityConfig 类
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.example.demo.auth.CaptchaDaoAuthenticationProvider;
import com.example.demo.auth.SecUserDetailsService;
import com.example.demo.repository.DmUserRepository;


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
    @Autowired
    private SecUserDetailsService secUserDetailsService;

    @Autowired 
    private DmUserRepository upmsUserRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/css/**", "/index").permitAll()     /*与之匹配的请求/CSS/*和/索引完全无障碍*/
                .antMatchers("/user/**").hasRole("USER")          /*与之匹配的请求/用户/*要求对用户进行身份验证,并且必须与用户角色*/
                .and().formLogin()
                .loginPage("/login").failureUrl("/login-error");                /*基于表单的身份验证是通过自定义登录页和故障url启用的。*/
    }
     /**
     * 使用数据库用户进行登录
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        CaptchaDaoAuthenticationProvider authProvider = new CaptchaDaoAuthenticationProvider();
        authProvider.setUserDetailsService(secUserDetailsService);
        authProvider.setUpmsUserRepository(upmsUserRepository);
        auth.authenticationProvider(authProvider);
    }

}

新建controller类

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {

    @RequestMapping("/")
    public String root() {
        return "redirect:/index";
    }

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

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

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

    @RequestMapping("/login-error")
    public String loginError(Model model) {
        model.addAttribute("loginError", true);
        return "login";
    }
}

新建用户实体类

package com.example.demo.domain;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@SuppressWarnings("serial")
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DmUser implements Serializable {
    
    @Id @GeneratedValue
    private Integer id;
    private String username;
    private String showname;
    private String password;
    private String role;
    
}

新建 BaseRepository类 使用的是JPA 查询用户信息

package com.example.demo.repository;

import java.io.Serializable;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;


@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

}
package com.example.demo.repository;


import org.springframework.stereotype.Repository;
import com.example.demo.domain.DmUser;

/**
 * 用户管理
 * @author llm
 */
@Repository
public interface DmUserRepository extends BaseRepository<DmUser, Integer> {
    
    /**
     * 根据用户名查询用户
     * @param userName 用户名
     * @return 用户对象。不存在则返回null
     */
    DmUser findByUsername(String username);
}

验证数据库用户信息相关的类

package com.example.demo.auth;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import com.example.demo.domain.DmUser;
import com.example.demo.repository.DmUserRepository;


public class CaptchaDaoAuthenticationProvider  extends DaoAuthenticationProvider {

    private DmUserRepository upmsUserRepository;
    public void setUpmsUserRepository(DmUserRepository upmsUserRepository) {
        this.upmsUserRepository = upmsUserRepository;
    }
    protected void additionalAuthenticationChecks(UserDetails userDetails,
              UsernamePasswordAuthenticationToken token)
            throws AuthenticationException {
        ReflectionUserSource userSource = new ReflectionUserSource();
        DmUser  upmsUser = (DmUser)userSource.getUser(userDetails);
        
    }
}

package com.example.demo.auth;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.example.demo.domain.DmUser;

/**
 * 用户信息认证
 * @author llm
 *
 */
public class SecUserDetails implements UserDetails{
    private DmUser user;
    public SecUserDetails(DmUser user) {
        this.user = user;
    }
    public DmUser getUser() {
        return user;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
        auths.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return user.getRole();
            }
        });
        return auths;
    }
    @Override
    public String getPassword() {
        return user.getPassword();
    }
    @Override
    public String getUsername() {
        return user.getUsername();
    }
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    @Override
    public boolean isEnabled() {
        return true;
    }
}

package com.example.demo.auth;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.ReflectionUtils;

public class ReflectionUserSource {

    private String userPropertyToUse = "user";
    
    public Object getUser(UserDetails user) {
        Method saltMethod = findSaltMethod(user);

        try {
            return saltMethod.invoke(user);
        }
        catch (Exception exception) {
            throw new AuthenticationServiceException(exception.getMessage(), exception);
        }
    }
    
    private Method findSaltMethod(UserDetails user) {
        Method saltMethod = ReflectionUtils.findMethod(user.getClass(),
                userPropertyToUse, new Class[0]);

        if (saltMethod == null) {
            PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(user.getClass(),
                    userPropertyToUse);

            if (pd != null) {
                saltMethod = pd.getReadMethod();
            }

            if (saltMethod == null) {
                throw new AuthenticationServiceException(
                        "Unable to find user method on user Object. Does the class '"
                                + user.getClass().getName()
                                + "' have a method or getter named '" + userPropertyToUse
                                + "' ?");
            }
        }

        return saltMethod;
    }

    
}

判断当前用户登录的信息

package com.example.demo.auth;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import com.example.demo.domain.DmUser;
import com.example.demo.repository.DmUserRepository;


public class CaptchaDaoAuthenticationProvider  extends DaoAuthenticationProvider {

    private DmUserRepository upmsUserRepository;
    public void setUpmsUserRepository(DmUserRepository upmsUserRepository) {
        this.upmsUserRepository = upmsUserRepository;
    }
    protected void additionalAuthenticationChecks(UserDetails userDetails,
              UsernamePasswordAuthenticationToken token)
            throws AuthenticationException {
        ReflectionUserSource userSource = new ReflectionUserSource();
        DmUser  upmsUser = (DmUser)userSource.getUser(userDetails);
        //判断用户信息
        
    }
}

页面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-springsecurity5">
<head>
    <title>Hello Spring Security</title>
    <meta charset="utf-8" />
   <!--  <link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}" /> -->
</head>
<body>
<div th:fragment="logout" class="logout" sec:authorize="isAuthenticated()">
    用户名: <span sec:authentication="name"></span> |
    角色: <span sec:authentication="principal.authorities"></span>
    <div>
        <form action="#" th:action="@{/logout}" method="post">
            <input type="submit" value="退出" />
        </form>
    </div>
</div> 
<h1>Hello Spring Security</h1>
<p>This is an unsecured page, but you can access the secured pages after authenticating.</p>
<ul>
    <li>Go to the <a href="/user/index" th:href="@{/user/index}">secured pages</a></li>
</ul>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login page</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}" />
</head>
<body>
<h1>Login page</h1>
<p>Example user: user / password</p>
<p th:if="${loginError}" class="error">Wrong user or password</p>
<form th:action="@{/login}" method="post">
    <label for="username">Username</label>:
    <input type="text" id="username" name="username" autofocus="autofocus" /> <br />
    <label for="password">Password</label>:
    <input type="password" id="password" name="password" /> <br />
    <input type="submit" value="Log in" />
</form>
<p><a href="/index" th:href="@{/index}">Back to home page</a></p>
</body>
</html>

登录成功后 user/index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Spring Security</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}" />
</head>
<body>
<div th:substituteby="index::logout"></div>
<h1>This is a secured page!</h1>
<p><a href="/index" th:href="@{/index}">Back to home page</a></p>
</body>
</html>

5.创建数据库用户

CREATE TABLE `dm_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `showname` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `role` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

INSERT INTO `dm_user` VALUES ('1', 'llm', '123456', '123456', 'ROLE_USER');

6.运行项目结果


image.png

7.项目结构


image.png
8.pom文件
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.llm</groupId>
    <artifactId>ceshi</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>securitydemo-1</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <!-- 使用阿里巴巴的数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

相关文章

网友评论

      本文标题:springboot 学习笔记(二)SpringBoot + S

      本文链接:https://www.haomeiwen.com/subject/vcygrctx.html