,我發現自己的答案與此文章的幫助:http://automateddeveloper.blogspot.cz/2014/03/securing-your-mobile-api-spring-security.html
也許有這樣做的更好的辦法,但這裏是我的解決方案:
我用了兩個結構F爾斯,先由雙方客戶應用程序和原有網絡應用和第二我的登錄頁面
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@Configuration
@EnableWebSecurity
@Order(1)
public class ConfigApi extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.csrf()
.disable()
.authorizeRequests().anyRequest().authenticated().and()
.addFilterBefore(new CustomFilter(), BasicAuthenticationFilter.class);
}
}
首先配置增加了過濾器上的URL的每個請求之前開始accesed資源與/ API/**
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
@EnableOAuth2Sso
@Order(2)
public class ConfigLogin extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/classification-login").authenticated();
}
}
第二個配置表示,對url/classification-login的請求需要進行身份驗證,但不添加任何過濾器。這意味着,用戶將被重定向到授權服務器,在那裏,他登錄和春季安全會(使用JSESSIONID)
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
public class CustomFilter extends GenericFilterBean {
@Value("${security.oauth2.client.clientId}")
private String clientId;
@Value("${security.oauth2.resource.tokenInfoUri}")
private String checkToken;
@Value("${security.oauth2.client.scope}")
private String scope;
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String authorization = httpServletRequest.getHeader("Authorization");
final String token = authorization.replace("Bearer ", "");
//Here I verify the user by token sent in headers (using tokenInfoUri of my authorization server)
final RestTemplate restTemplate = new RestTemplate();
final TokenInfo tokenInfo = restTemplate.getForObject(checkToken + "?token=" + token, TokenInfo.class);
final String userName = tokenInfo.getUserName();
final Set<String> scopes = new HashSet<>();
scopes.add(scope);
final OAuth2Request oAuth2Request = new OAuth2Request(Collections.<String, String>emptyMap(), clientId, null, true, scopes, null, null, null, null);
final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
final UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userName, null, authorities);
final OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, usernamePasswordAuthenticationToken);
oAuth2Authentication.setAuthenticated(true);
final SecurityContextImpl securityContext = (SecurityContextImpl) SecurityContextHolder.getContext();
securityContext.setAuthentication(oAuth2Authentication);
} catch (Exception ignore) {
System.out.println(ignore);
}
chain.doFilter(request, response);
}
}
這裏是我的過濾器,基本上我只是檢查頭在申請保存在他的會話的認證,閱讀令牌並通過令牌對用戶進行身份驗證。 (如果沒有道理,它捕獲異常,並繼續[可能會做的更好的未來,現在沒有時間吧])
結果:
如果用戶使用我的webapp他登錄使用/ classification-login,然後允許他使用api,因爲spring安全將他的身份驗證保存在他的會話中。
如果有人想利用他的應用程序,他需要用他的應用程序相同的授權服務器的API,讓他的令牌,並通過它在頭請求。
如果有人知道一個更好的解決方案隨意評論,我花了太多時間在這,所以我不打算進一步調查的任何。