假设我们需要实现一个基于Spring Boot的Web应用程序,用于实现用户登录和权限管理。以下是我们可能需要实现的功能列表: 用户注册和登录功能 权限控制功能:例如管理员和普通用户之间的权限差异 记录用户登录信息的功能:例如最后登录时间和登录IP等代码实现
时间: 2024-02-28 11:56:25 浏览: 65
好的,我将给出一个简单的代码实现,供参考。
首先,我们可以创建一个名为 `user-management-spring-boot-starter` 的 Maven 项目,作为自定义 starter 的实现。该 starter 将包含我们需要实现的所有功能。
在 starter 项目的 `src/main/java` 目录下,创建一个 `UserManagementAutoConfiguration` 类。该类将包含我们需要实现的所有自动配置。
```java
@Configuration
@EnableConfigurationProperties(UserManagementProperties.class)
public class UserManagementAutoConfiguration {
private final UserManagementProperties properties;
public UserManagementAutoConfiguration(UserManagementProperties properties) {
this.properties = properties;
}
@Bean
public JdbcTemplate jdbcTemplate() {
DataSource dataSource = DataSourceBuilder.create()
.url(properties.getDatabaseUrl())
.username(properties.getDatabaseUsername())
.password(properties.getDatabasePassword())
.driverClassName(properties.getDatabaseDriverClassName())
.build();
return new JdbcTemplate(dataSource);
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl(jdbcTemplate());
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService());
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
@Bean
public LoginFilter loginFilter() throws Exception {
LoginFilter filter = new LoginFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.setFilterProcessesUrl(properties.getLoginUrl());
filter.setUsernameParameter(properties.getUsernameParameter());
filter.setPasswordParameter(properties.getPasswordParameter());
filter.setSuccessHandler(new LoginSuccessHandler());
filter.setFailureHandler(new LoginFailureHandler());
return filter;
}
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter filter = new LogoutFilter(properties.getLogoutUrl(),
new SecurityContextLogoutHandler());
filter.setLogoutSuccessHandler(new LogoutSuccessHandler());
return filter;
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new AccessDeniedHandlerImpl();
}
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return new LoginUrlAuthenticationEntryPoint(properties.getLoginUrl());
}
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(Collections.singletonList(authenticationProvider()));
}
}
```
在 `UserManagementAutoConfiguration` 中,我们使用 `@ConfigurationProperties` 注解来定义我们的配置,例如数据库连接信息、登录页面路径等等。我们还使用 `@ConditionalOnProperty` 注解来指定配置属性,以便在不同的条件下启用或禁用某些模块。
```java
@ConfigurationProperties(prefix = "user.management")
public class UserManagementProperties {
private String databaseUrl;
private String databaseUsername;
private String databasePassword;
private String databaseDriverClassName;
private String loginUrl;
private String logoutUrl;
private String usernameParameter;
private String passwordParameter;
private String rolePrefix;
// getters and setters
}
```
接下来,我们使用 `JdbcTemplate` 来实现用户登录和注册的功能,使用 `AOP` 来实现权限控制,使用 `Filter` 来记录用户登录信息等。这些具体实现可以在 `com.example.usermanagement` 包中进行。
我们可以使用 `UserDetailsService` 接口来获取用户信息。下面是一个简单的实现,使用 `JdbcTemplate` 来查询数据库。
```java
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private final JdbcTemplate jdbcTemplate;
public UserDetailsServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List<GrantedAuthority> authorities = new ArrayList<>();
String sql = "SELECT username, password, role FROM users WHERE username=?";
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, username);
if (rows.isEmpty()) {
throw new UsernameNotFoundException("User not found");
}
Map<String, Object> row = rows.get(0);
String password = (String) row.get("password");
String role = (String) row.get("role");
authorities.add(new SimpleGrantedAuthority(role));
return new User(username, passwordEncoder().encode(password), authorities);
}
}
```
我们可以使用 `BCryptPasswordEncoder` 来加密用户密码。
```java
public class BCryptPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt());
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
}
```
我们可以使用 `AOP` 来实现权限控制。下面是一个简单的实现,使用 `@PreAuthorize` 注解来限制访问。
```java
@Service
public class UserServiceImpl implements UserService {
@Override
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(String username) {
// delete user from database
}
}
```
我们可以使用 `Filter` 来记录用户登录信息。下面是一个简单的实现,使用 `HttpServletRequestWrapper` 来包装请求。
```java
public class LoginFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
// wrap request
request = new LoginHttpServletRequestWrapper(request);
// call super method
return super.attemptAuthentication(request, response);
}
}
```
最后,我们将我们的 starter 打包成一个 JAR 文件,并将其上传到 Maven 仓库中,以供其他项目使用。
在使用 starter 的项目中,只需要在 `pom.xml` 文件中添加相关依赖,就可以使用我们自定义的功能模块了。例如,可以添加以下依赖:
```xml
<dependency>
<groupId>com.example</groupId>
<artifactId>user-management-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
```
阅读全文