我们正在使用stormpath with Java&还试图在同一个应用程序中将表单Login和REST API身份验证结合起来。
我已按照此处所述设置了stormpath servlet插件https://docs.stormpath.com/java/servlet-plugin/quickstart.html ...这非常正常。
现在,在同一个应用程序中,我们有API,我已经使用stormpath实现了oAuth身份验证,请参阅此处http://docs.stormpath.com/guides/api-key-management/
第一次访问令牌请求可以通过在请求标头中发送Basic Base64(keyId:keySecret)
并在正文中发送grant_type = client_credentials
来正常工作。访问令牌正在很好地返回。但是,尝试使用标头Bearer <the-obtained-access-token>
验证后续请求之前甚至没有命中应用程序
返回以下json错误消息...
{
"error": "invalid_client",
"error_description": "access_token is invalid."
}
这很令人困惑,因为我在整个应用程序中设置了断点,我很确定在stormpath启动并返回此错误之前,API请求没有到达应用程序中的任何位置。即使stormpath在进入REST接口之前以某种方式拦截了请求,这条消息对我来说没有任何意义,因为我肯定使用从第一次调用获得的有效访问令牌进行后续API调用以获取访问权限 - 令牌。
我已经没想到为什么会发生这种情况,但我怀疑它可能与stormpath配置有关,特别是与组合 用于Web视图的登录/身份验证和用于REST端点的oAuth身份验证。话虽如此,这就是我的stormpath.properties的样子。希望这可以帮助指出我可能做错的任何事情。
stormpath.application.href=https://api.stormpath.com/v1/applications/[app-id]
stormpath.web.filters.authr=com.app.security.AuthorizationFilter
stormpath.web.request.event.listener = com.app.security.AuthenticationListener
stormpath.web.uris./resources/**=anon
stormpath.web.uris./assets/**=anon
stormpath.web.uris./v1.0/**=anon
stormpath.web.uris./** = authc,authr
stormpath.web.uris./**/**=authc,authr
对此的帮助将受到高度赞赏。
答案 0 :(得分:2)
问题可能与不正确的请求有关。
您是否可以在应用中尝试此代码?:
private boolean verify(String accessToken) throws OauthAuthenticationException {
HttpRequest request = createRequestForOauth2AuthenticatedOperation(accessToken);
AccessTokenResult result = Applications.oauthRequestAuthenticator(application)
.authenticate(request);
System.out.println(result.getAccount().getEmail() + " was successfully verified, you can allow your protect operation to continue");
return true;
}
private HttpRequest createRequestForOauth2AuthenticatedOperation(String token) {
try {
Map<String, String[]> headers = new LinkedHashMap<String, String[]>();
headers.put("Accept", new String[]{"application/json"});
headers.put("Authorization", new String[]{"Bearer " + token});
HttpRequest request = HttpRequests.method(HttpMethod.GET)
.headers(headers)
.build();
return request;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
答案 1 :(得分:1)
我准备了一个示例,演示了oauth令牌创建以及使用访问令牌对受保护页面的授权访问。
它构建了Stormpath SDK中的servlet示例。回购可以在这里找到:https://github.com/stormpath/stormpath-java-oauth-servlet-sample
它演示了运行servlet应用程序并使用带外程序获取并使用oauth令牌来访问受保护资源。
oauth部分的核心在TokenAuthTest.java
:
public class TokenAuthTest {
public static void main(String[] args) throws Exception {
String command = System.getProperty("command");
if (command == null || !("getToken".equals(command) || "getPage".equals(command))) {
System.err.println("Must supply a command:");
System.err.println("\t-Dcommand=getToken OR");
System.err.println("\t-Dcommand=getPage OR");
System.exit(1);
}
if ("getToken".equals(command)) {
getToken();
} else {
getPage();
}
}
private static final String APP_URL = "http://localhost:8080";
private static final String OAUTH_URI = "/oauth/token";
private static final String PROTECTED_URI = "/dashboard";
private static void getToken() throws Exception {
String username = System.getProperty("username");
String password = System.getProperty("password");
if (username == null || password == null) {
System.err.println("Must supply -Dusername=<username> -Dpassword=<password> on the command line");
System.exit(1);
}
PostMethod method = new PostMethod(APP_URL + OAUTH_URI);
method.setRequestHeader("Origin", APP_URL);
method.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
method.addParameter("grant_type", "password");
method.addParameter("username", username);
method.addParameter("password", password);
HttpClient client = new HttpClient();
client.executeMethod(method);
BufferedReader br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
String readLine;
while(((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
private static void getPage() throws Exception {
String token = System.getProperty("token");
if (token == null) {
System.err.println("Must supply -Dtoken=<access token> on the command line");
System.exit(1);
}
GetMethod method = new GetMethod(APP_URL + PROTECTED_URI);
HttpClient client = new HttpClient();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " without token...");
int returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
System.out.println();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " with token...");
method.addRequestHeader("Authorization", "Bearer " + token);
returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
}
}