Spring rest 配置jwt 安全验证

在用spring + mybatis 作项目。以前安全验证用basic 方式如今想换成jwt。java

jwt :web

JWS模式对这个内容进行了数字化签名。这个内容被用来存放JWT的声明.服务端签名出JWT而且发送到客户端,并在用户成功认证后进行应答。服务器指望客户端在下次请求的时候将JWS做为请求的一部分,发送回服务端。算法

  若是咱们处理的客户端是欺骗者则么办?这就是签名(signature)须要出场的地方了。签名携带了完整的可验证的信息。换句话说,服务器能够确认,接收到的JWT声明里的JWS是没有通过欺骗客户端、中间者进行修改的。spring

  服务端经过验证消息的签名来确保客户端没有修改声明。若是服务端检测到任何修改,能够采起适当的动做(拒绝此次请求或者锁定客户端之类的)api

  客户端一样能够验证签名,为了作到这点,客户端也须要服务端的secret(密钥)(若是这个JWT签名是HMAC算法),或者须要服务端对公钥(若是这个WJT是数字化签名)安全

  特别注意:对于JWS,荷载(声明部分)没有进行加密,因此,不要发送任何敏感信息.服务器

 

 

首先在web.xml 中session

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-mybatis.xml
			/WEB-INF/spring-security.xml
			classpath:applicationContext.xml
		</param-value>
	</context-param>



	<!-- Security -->
	<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>


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


	<servlet>
		<servlet-name>fly.fky</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>fly.fky</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

 

spring-sucurity.xmlmybatis

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
	<context:annotation-config />
	<global-method-security pre-post-annotations="enabled" />
	<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
		<beans:constructor-arg value="ThisIsASecretSoChangeMe" />
	</beans:bean>
	<!-- 
	<authentication-manager id="authenticationManager"
		erase-credentials="false">
		<authentication-provider user-service-ref="userService">
			<password-encoder ref="passwordEncoder"></password-encoder>
		</authentication-provider>
	</authentication-manager>
	<http pattern="/**" entry-point-ref="unauthorizedEntryPoint"
		create-session="stateless">
		<csrf disabled="true" />
		<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter" />
	</http>


	<beans:bean id="jwtAuthenticationFilter"
		class="fly.fky.restapi.security.JwtAuthenticationFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
		<beans:property name="authenticationSuccessHandler"
			ref="jwtAuthenticationSuccessHandler" />
	</beans:bean>

	<beans:bean id="unauthorizedEntryPoint"
		class="fly.fky.restapi.service.UnauthorizedEntryPoint" />


	<beans:bean id="jwtAuthenticationSuccessHandler"
		class="fly.fky.restapi.security.JwtAuthenticationSuccessHandler" />


	<!-- authentication manager -->

	<authentication-manager id="authenticationManager">
		<authentication-provider ref="jwtAuthenticationProvider">
		</authentication-provider>
	</authentication-manager>

	<beans:bean id="jwtAuthenticationProvider"
		class="fly.fky.restapi.security.JwtAuthenticationProvider" />
</beans:beans>

 

jwt filter 文件app

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	public JwtAuthenticationFilter() {
		super("/**");
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		String header = request.getHeader("Authorization");

        if (header == null || !header.startsWith("Bearer ")) {
        	throw new RestAPIAuthenticationException(MessageToClientFormat.formateMsg("No JWT token found in request headers"));
        }

        String authToken = header.substring(7);

       return JwtTokenUtil.getAuthentication(authToken);
	}

}

JwtAuthenticationProvider

public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

	@Resource
	private UserService userService;
	
	
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
		
		if (authentication.getCredentials() == null) {
			logger.debug("Authentication failed: no credentials provided");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
		
		String presentedPassword = authentication.getCredentials().toString();

		if (!userService.isPasswordMatched(presentedPassword, userDetails.getPassword())) {
			logger.debug("Authentication failed: password does not match stored value");

			throw new BadCredentialsException(messages.getMessage(
					"AbstractUserDetailsAuthenticationProvider.badCredentials",
					"Bad credentials"));
		}
	}

	@Override
	protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		return userService.loadUserByUsername(username);
		
	}

}
相关文章
相关标签/搜索