jsp 语言 JSP 整合 Spring Security 实现登录认证示例

JSP阿木 发布于 23 天前 4 次阅读


JSP 整合 Spring Security 实现登录认证示例

随着互联网技术的不断发展,Web应用程序的安全问题日益突出。为了确保Web应用程序的安全性,登录认证是必不可少的环节。本文将围绕JSP(JavaServer Pages)语言,结合Spring Security框架,实现一个简单的登录认证示例。通过本文的学习,读者可以了解到JSP与Spring Security的整合方法,以及如何实现基本的用户认证和授权。

环境准备

在开始之前,我们需要准备以下环境:

1. JDK 1.8 或更高版本

2. Maven 3.0 或更高版本

3. IntelliJ IDEA 或其他Java IDE

4. Tomcat 9.0 或更高版本

项目结构

以下是项目的目录结构:


src/


|-- main/


| |-- java/


| | |-- com/


| | | |-- example/


| | | | |-- controller/


| | | | | |-- LoginController.java


| | | | |-- security/


| | | | | |-- WebSecurityConfig.java


| | | | |-- model/


| | | | | |-- User.java


| | | | |-- service/


| | | | | |-- UserService.java


| | | | |-- repository/


| | | | | |-- UserRepository.java


| |-- resources/


| | |-- application.properties


| |-- webapp/


| |-- WEB-INF/


| | |-- views/


| | | |-- login.jsp


| | | |-- index.jsp


| |-- index.jsp


|-- pom.xml


1. 创建项目

使用Maven创建一个Java Web项目,并添加以下依赖:

xml

<dependencies>


<!-- Spring Boot Starter Web -->


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-web</artifactId>


</dependency>


<!-- Spring Boot Starter Security -->


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-security</artifactId>


</dependency>


<!-- Thymeleaf -->


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-thymeleaf</artifactId>


</dependency>


<!-- MySQL Connector -->


<dependency>


<groupId>mysql</groupId>


<artifactId>mysql-connector-java</artifactId>


<scope>runtime</scope>


</dependency>


</dependencies>


2. 配置数据库

在`application.properties`文件中配置数据库连接信息:

properties

spring.datasource.url=jdbc:mysql://localhost:3306/example_db?useSSL=false&serverTimezone=UTC


spring.datasource.username=root


spring.datasource.password=root


spring.jpa.hibernate.ddl-auto=update


3. 创建实体类

在`model/User.java`文件中创建用户实体类:

java

package com.example.model;

import javax.persistence.;


import java.util.Set;

@Entity


@Table(name = "users")


public class User {


@Id


@GeneratedValue(strategy = GenerationType.IDENTITY)


private Long id;

@Column(unique = true)


private String username;

private String password;

@ManyToMany(fetch = FetchType.EAGER)


@JoinTable(


name = "user_roles",


joinColumns = @JoinColumn(name = "user_id"),


inverseJoinColumns = @JoinColumn(name = "role_id")


)


private Set<Role> roles;

// Getters and setters...


}


在`model/Role.java`文件中创建角色实体类:

java

package com.example.model;

import javax.persistence.;


import java.util.Set;

@Entity


@Table(name = "roles")


public class Role {


@Id


@GeneratedValue(strategy = GenerationType.IDENTITY)


private Long id;

@Column(unique = true)


private String name;

@ManyToMany(mappedBy = "roles")


private Set<User> users;

// Getters and setters...


}


4. 创建数据访问层

在`repository/UserRepository.java`文件中创建用户数据访问接口:

java

package com.example.repository;

import com.example.model.User;


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

public interface UserRepository extends JpaRepository<User, Long> {


User findByUsername(String username);


}


在`repository/RoleRepository.java`文件中创建角色数据访问接口:

java

package com.example.repository;

import com.example.model.Role;


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

public interface RoleRepository extends JpaRepository<Role, Long> {


}


5. 创建业务逻辑层

在`service/UserService.java`文件中创建用户业务逻辑类:

java

package com.example.service;

import com.example.model.User;


import com.example.repository.UserRepository;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.security.crypto.password.PasswordEncoder;


import org.springframework.stereotype.Service;

@Service


public class UserService {


@Autowired


private UserRepository userRepository;

@Autowired


private PasswordEncoder passwordEncoder;

public User saveUser(User user) {


user.setPassword(passwordEncoder.encode(user.getPassword()));


return userRepository.save(user);


}

public User findByUsername(String username) {


return userRepository.findByUsername(username);


}


}


6. 创建控制器

在`controller/LoginController.java`文件中创建登录控制器:

java

package com.example.controller;

import com.example.model.User;


import com.example.service.UserService;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.security.core.Authentication;


import org.springframework.security.core.context.SecurityContextHolder;


import org.springframework.stereotype.Controller;


import org.springframework.ui.Model;


import org.springframework.web.bind.annotation.GetMapping;


import org.springframework.web.bind.annotation.PostMapping;

@Controller


public class LoginController {


@Autowired


private UserService userService;

@GetMapping("/login")


public String login() {


return "login";


}

@PostMapping("/login")


public String login(String username, String password, Model model) {


User user = userService.findByUsername(username);


if (user != null && passwordEncoder.matches(password, user.getPassword())) {


Authentication authentication = new org.springframework.security.authentication.UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());


SecurityContextHolder.getContext().setAuthentication(authentication);


return "redirect:/";


} else {


model.addAttribute("error", "Invalid username or password");


return "login";


}


}


}


7. 创建安全配置

在`security/WebSecurityConfig.java`文件中创建Spring Security配置类:

java

package com.example.security;

import com.example.model.User;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.context.annotation.Bean;


import org.springframework.context.annotation.Configuration;


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 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration


@EnableWebSecurity


public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired


private UserService userService;

@Override


protected void configure(AuthenticationManagerBuilder auth) throws Exception {


auth.userDetailsService(userService).passwordEncoder(passwordEncoder());


}

@Override


protected void configure(HttpSecurity http) throws Exception {


http


.authorizeRequests()


.antMatchers("/login").permitAll()


.anyRequest().authenticated()


.and()


.formLogin()


.loginPage("/login")


.permitAll()


.and()


.logout()


.permitAll();


}

@Bean


public PasswordEncoder passwordEncoder() {


return new BCryptPasswordEncoder();


}


}


8. 创建视图

在`webapp/WEB-INF/views/login.jsp`文件中创建登录页面:

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<html>


<head>


<title>Login</title>


</head>


<body>


<form action="login" method="post">


<div>


<label for="username">Username:</label>


<input type="text" id="username" name="username" required>


</div>


<div>


<label for="password">Password:</label>


<input type="password" id="password" name="password" required>


</div>


<div>


<input type="submit" value="Login">


</div>


</form>


<c:if test="${not empty error}">


<div style="color: red">${error}</div>


</c:if>


</body>


</html>


在`webapp/WEB-INF/views/index.jsp`文件中创建首页:

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<html>


<head>


<title>Home</title>


</head>


<body>


<h1>Welcome to the Home Page!</h1>


<div>


<a href="/logout">Logout</a>


</div>


</body>


</html>


9. 运行项目

启动Tomcat服务器,并访问`http://localhost:8080/`。在登录页面输入用户名和密码,成功登录后,将跳转到首页。

总结

本文通过JSP和Spring Security框架,实现了一个简单的登录认证示例。读者可以根据实际需求,对示例进行扩展和优化。在实际项目中,还需要考虑更多的安全因素,如密码加密、跨站请求伪造(CSRF)等。希望本文对读者有所帮助。