Java Programming

Spring MVC Security

Dependency

Truy cập vào link https://start.spring.io/ thêm Dependency: Spring Security

SecurityConfig

Trong webapp tạo SecurityConfig.java với nội dung sau:

package webapp;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request -> 
                request.requestMatchers("/", "/styles/*", "/auth/login", "/auth/register")
                .permitAll()
                .anyRequest().authenticated())      
            .formLogin(form -> form.loginPage("/auth/login")
                .defaultSuccessUrl("/", true)
                .permitAll())
            .logout(LogoutConfigurer::permitAll);
        return http.build();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Tạo models

Tạo enum Role

Trong thư mục models tạo Role.java với nội dung sau

package webapp.models;
public enum Role {
    Admin,
    User
}

Tạo class Member

Trong thư mục models tiếp tục tạo Member.java với nội dung sau:

package webapp.models;
@Entity
public class Member {
    @Id
    @Column(name = "MemberId")
    private String id;
    private String username;
    private String password;
    private Role role;
    public Member(String id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    public Member() {
    }
    public String getId() {
        return id;
    }
    public String getPassword() {
        return password;
    }
    public Role getRole() {
        return role;
    }
    public String getUsername() {
        return username;
    }
    public void setId(String id) {
        this.id = id;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setRole(Role role) {
        this.role = role;
    }
    public void setUsername(String username) {
        this.username = username;
    }
}

Tạo class MemberRepository

Trong models tiếp tục tạo thêm MemberRepository.java với nội dung sau

public interface MemberRepository extends JpaRepository {
    Member findByUsername(String username);
}

Tạo services

Trong src/main/java/webapp tạo thư mục services

Tạo class Helper

Trong thư mục services tạo Helper.java với nội dung sau:

package webapp.services;
public class Helper {
        public static String randomString(int len){
        StringBuilder sb = new StringBuilder(len);
        String pattern = "1234567890qwertyuiopasdfghjklzxcvbnm";
        Random random = new Random();
        for(int i = 0; i < len; i++){
            sb.append(pattern.charAt(random.nextInt(pattern.length())));
        }
        return sb.toString();
    }
}

Tạo class MemberService

package webapp.services;
@Service
public class MemberService implements UserDetailsService {
    @Autowired
    MemberRepository repository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Member member = repository.findByUsername(username);
        if(member == null){
            return null;
        }
        return User.withUsername(member.getUsername())
            .password(member.getPassword())
            .roles(member.getRole().name())
            .build();
    }
}

Tạo controller

Tạo AuthController

Trong controllers tạo AuthController.java với nội dung sau:

package webapp.controllers;
@Controller
public class AuthController {
    @Autowired
    private MemberRepository repository;
    @Autowired
    private PasswordEncoder encoder;
    @GetMapping("/auth/login")
    public String login(){
        return "auth/login";
    }
    @GetMapping("/auth/register")
    public String register(){
        return "auth/register";
    }    
    @PostMapping("/auth/register")
    public String register(@Validated @ModelAttribute Member obj){
        obj.setId(Helper.randomString(32));
        obj.setPassword(encoder.encode(obj.getPassword()));
        obj.setRole(Role.User);
        Member ret = repository.save(obj);
        if(ret != null){
            return "redirect:/auth/login?success";
        }
        return "auth/register";
    }
}

Tạo View

Trong thư mục resources/templates tạo thư mục auth

Tạo view register

Trong thư mục auth tạo register.html với nội dung sau:

<form method="post">
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
    <div>
        <label for="usr">Username</label>
        <div>
            <input type="text" name="username" id="usr">
        </div>
    </div>
    <div>
        <label for="pwd">Password</label>
        <div>
            <input type="password" name="password" id="pwd">
        </div>
    </div>
    <div>
        <button>Register</button>
        <a href="/auth/login">Login</a>
    </div>
</form>