springsecurity ajax login 与普通longin请求并存

spring security ——普通login请求与ajax login请求并存

正常的配置流程就不从头开始说了,网上都有,现在把我遇到的几个问题说一下。

第一个就是当系统进行api调用的时候,或者说Ajax请求时,后台通过判断返回一个json串而不是直接返回一个页面(login.html,403.jsp)。
下面是直接返回页面配置的代码:

<security:http use-expressions="true">
        <!--登录和静态资源,任何人都可以访问-->

        <security:intercept-url pattern="/login*" access="permitAll"/>
        <security:intercept-url pattern="/v*/**" access="permitAll"/>


        <!--其它所有页面都要求登录-->
        <security:intercept-url pattern="/**" access="isAuthenticated()"/>
        <!--<security:intercept-url pattern="/*shtml" access="ROLE_USER"/>-->
        <security:form-login
                login-page='/login.shtml'
                login-processing-url="/j_spring_security_check"
                authentication-failure-url="/login-error.shtml"
                default-target-url="/main.shtml"
                always-use-default-target="true"/>
        <security:request-cache ref="requestCache"/>
    </security:http>

 <bean id="myAuthenticationProvider"
          class="***.***.***.MyAuthenticationProvider">
        <property name="userDetailsService" ref="myUserDetailsService"/>
        <property name="hideUserNotFoundExceptions" value="false"/>
    </bean>

    <bean id="myUserDetailsService"
          class="***.***.***.MyUserDetailsService">
    </bean>
<!--认证管理器 用户名密码在MyUserDetailsService中验证-->
    <security:authentication-manager>
        <security:authentication-provider ref='myAuthenticationProvider'>
        </security:authentication-provider>
    </security:authentication-manager>

下面是验证部分的实现代码:

public class MyUserDetailsService implements UserDetailsService {
        private static final Logger logger = Logger.getLogger(MyUserDetailsService.class);

        @Autowired
        private UserService userService;


        public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {

            return buildUser(userName);
        }

        private MyUserDetails buildUser(String userId) {
            Set<String> roleSet = new HashSet<>(1);

            HBUser user = userService.selectUser(userId);
            if (user == null) {
                throw new UsernameNotFoundException("User not exist");
            }

            roleSet.add(user.getRole());
            return new MyUserDetails(user, buildUserAuthority(roleSet));
        }

        private List<GrantedAuthority> buildUserAuthority(Set<String> userRoles) {

            Set<GrantedAuthority> setAuths = new HashSet<>();

            // Build user's authorities
            for (String userRole : userRoles) {
                setAuths.add(new SimpleGrantedAuthority(userRole));
            }

            return new ArrayList<>(setAuths);
        }
}

上面就是前一阶段的配置,后面就是问题的解决部分:
在已有的基础上再加一个<security:http auto-config="true" use-expressions="true" pattern="/rest/**">表达式语言配置访问控制

<security:http auto-config="true" use-expressions="true" pattern="/r**/**">
        <security:form-login
                login-processing-url="/r*/s*/login-processing"
                login-page="/r*/s*/login-page.do"
                authentication-failure-url="/r*/s*/authentication-failure.do"
                default-target-url="/r*/s*/default-target.do"
                always-use-default-target="true" />
        <security:logout logout-url="/r*/s*/logout-url"
                         logout-success-url="/r*/s*/logout-success.do"/>

        <!-- REST services can be secured here, will respond with JSON instead of HTML -->
        <!--<security:intercept-url pattern="/rest/calendar/**" access="hasRole('ROLE_USER')" />-->

        <!-- other REST intercept-urls go here -->
        <security:intercept-url pattern="/rest/security/default-target.do" access="isAuthenticated()" />
        <security:intercept-url pattern="/rest/security/*.do" access="permitAll"/>
        <security:intercept-url pattern="/rest/engine/**" access="permitAll"/>
        <security:intercept-url pattern="/rest/public/**" access="permitAll"/>
        <!--相关接口-->
        <security:intercept-url pattern="/r*/a*/update.do" access="permitAll"/>
        <security:intercept-url pattern="/r*/a*/done.do" access="permitAll"/>
        <security:intercept-url pattern="/r*/a*/quiet.do" access="permitAll"/>
        <!-- end it with a catch all -->
        <security:intercept-url pattern="/rest/**" access="isAuthenticated()" />


        <!-- reference to the shared request cache -->
        <security:request-cache ref="requestCache"/>
    </security:http>

然后我只需要把上面配置中的接口实现就行
只要出现请求配置中的接口就会跳到下面相应的路径

@Controller
@RequestMapping(value = "/r*/s*")
public class RestAuthenticationController {
    private static final Logger logger = Logger.getLogger(RestAuthenticationController.class);

    @Autowired
    UserService userService;

    public HttpHeaders getJsonHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        return headers;
    }

    @RequestMapping(value = "/login-page.do", method = RequestMethod.GET)
    public ResponseEntity<String> apiLoginPage() {
        return new ResponseEntity<>(getJsonHeaders(), HttpStatus.UNAUTHORIZED);
    }

    @RequestMapping(value = "/authentication-failure.do", method = RequestMethod.GET)
    @ResponseBody
    public HBResponse apiAuthenticationFailure(HttpSession session) {
        // return HttpStatus.OK to let your front-end know the request completed
        // (no 401, it will cause you to go back to login again, loops, not good)
        // include some message code to indicate unsuccessful login

        Object err = session.getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
        HBResponse response;
        if (err instanceof UsernameNotFoundException) {
            response = new HBResponse(ResultCode.USER_NOT_EXIST, "user not exist.");
        } else if (err instanceof BadCredentialsException) {
            response = new HBResponse(ResultCode.USERNAME_OR_PASSWORD_ERROR, "password error.");
        } else if (err instanceof LockedException) {
            response = new HBResponse(ResultCode.SERVER_ERROR, "user locked.");
        } else if (err instanceof DisabledException) {
            response = new HBResponse(ResultCode.SERVER_ERROR, "user disabled.");
        } else if (err instanceof CredentialException) {
            response = new HBResponse(ResultCode.SERVER_ERROR, "credintial error: " + err);
        } else {
            response = new HBResponse(ResultCode.SERVER_ERROR, "unknown error: " + err);
        }

        return response;
    }

第一次写博客,很多东西都不完善,如有错误,请大家多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值