添加具有弹簧安全性的自定义登录控制器

2022-09-04 21:54:20

弹簧 petclinic 示例应用构建的应用已通过自定义登录表单添加了 spring 安全性。

该应用程序没有本教程建议的 WebMvcConfiguration.java 类。相反,它在 中具有以下行:mvc-core-config.xml

<mvc:view-controller path="/login" view-name="login" />

我已经在eclipse中完成了对整个工作区中该术语的关键字搜索,但没有控制器可见。我还查看了上面教程链接中提到的示例项目,但在那里也找不到“”控制器。Ctrl-H/loginmessages-jc/login

如何添加一个控制器,该控制器将使用标准用户名和密码执行春季身份验证,但这也将允许我在提交“/login”url处的登录表单时随后向身份验证过程添加其他代码?

它是否像将以下内容添加到以下内容一样简单:SomeOtherController.java

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String showLoginForm(Model model) {
        //what goes here?       
    return "public/loginform";
}

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String processLoginForm(HttpSession session, @ModelAttribute("user") User user,
        BindingResult result, Model model, final RedirectAttributes redirectAttributes)
{
        //what goes here?
    return "secure/main";
}

答案 1

在spring-security-core jar中,有一个接口UserDetailsService,它有一个方法

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

您可以实现此接口并创建自己的逻辑代码,例如

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) {
    User user = userService.findUserByUsername(username);
    if (user != null) {
        String password = user.getPassword();
        boolean enabled = user.getActive();
        boolean accountNonExpired = user.getActive();
        boolean credentialsNonExpired = user.getActive();
        boolean accountNonLocked = user.getActive();

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (Role r : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(r.getAuthority()));
        }
        org.springframework.security.core.userdetails.User securedUser = new org.springframework.security.core.userdetails.User(
                username, password, enabled, accountNonExpired,
                credentialsNonExpired, accountNonLocked, authorities);
        return securedUser;
    } else {
        throw new UsernameNotFoundException(
                "Unable to find user with username provided!!");
    }
}

然后使用创建 DaoAuthenticationProvider 的对象

<bean id="daoAuthenticationProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="userDetailsService"></property>
</bean>

最后,将此 DaoAuthenticationProvider 提供给 ProviderManager

<bean class="org.springframework.security.authentication.ProviderManager">
    <constructor-arg>
        <list>
            <ref bean="daoAuthenticationProvider" />
        </list>
    </constructor-arg>
</bean>

<security:authentication-manager>
    <security:authentication-provider
        user-service-ref="userDetailsService">
        <security:password-encoder hash="plaintext"></security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>

添加网页.xml详细信息

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-config/spring-*.xml</param-value>
</context-param>


<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

答案 2

为此,您可以通过从 org.springframework 实现 AuthenticationProvider 来使用自己的 CustomAuthenticationProvider。安全。身份验证并覆盖公共身份验证身份验证(身份验证身份验证)方法。

下面给出了代码示例

public class CustomAuthenticationProvider implements AuthenticationProvider {

@Override
public Authentication authenticate(Authentication authentication)
        throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();
    List<GrantedAuthority> grantedAuths = new ArrayList<>();


       //validate and do your additionl logic and set the role type after your validation. in this code i am simply adding admin role type
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN" ));



    return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
}

@Override
public boolean supports(Class<?> arg0) {
    return true;
}

} 

所以默认的登录处理程序,即/login(POST)将由此处理。


推荐