我一直试图将其注册为:
public ApplicationConfig(){ super(); addRestResourceClasses(getMyResourceClasses()); register(new OAuth1ServerFeature(new DefaultOAuth1Provider(),"/oauth/access_token","/oauth/request_token")); }
但是,当我注册OAuth1ServerFeature时,在尝试访问我的资源时会得到404.
似乎无法找到任何实施泽西oauth支持的示例/教程!
是否有一个简单的组件可以插入我的jax-rs服务以启用oauth支持?
解决方法
关于在泽西岛使用OAuth1服务器(又名提供商)功能的信息绝对缺乏示例 – 我不记得一个技术主题,揭示了如此少有用的谷歌信息.我几乎继续寻找另一种解决方案,因为它让我想到也许它不起作用.但是,有了一些毅力,我可以说它不仅可以使用,而且似乎运作得相当好.当然,如果您已经使用Jersey作为REST API – 您不需要任何额外的库.
我不是OAuth1专家 – 我强烈建议那些尝试此操作的人阅读.我也在这里假设你有泽西岛工作,理解像ContainerRequestFilters这样的东西,并且还有一些内部手段来授权用户.
我的示例还使用了优秀的JAX-RS OSGi连接器 – 唯一真正的区别是,我们使用OSGi捆绑上下文通过OSGI服务注册OAuth1功能,常规Jersey用户需要通过其正常的Application / Server配置模型进行配置.
初始化
您必须创建OAuth1功能 – 并为其提供提供程序:
DefaultOAuth1Provider oap = new DefaultOAuth1Provider(); Feature oaFeature = new OAuth1ServerFeature(oap,"oauth1/request_token","oauth1/access_token");
别忘了在泽西岛注册oaFeature!
DefaultOAuth1Provider完全基于内存 – 这对我们来说很好.许多人希望持久访问令牌以便在服务器重启时使用,这将需要扩展的子类(或干净的实现)
添加您的消费者密钥和秘密
我花了一段时间才意识到消费者不是用户而是客户,即应用程序.如果您没有为希望连接的每个消费者(也称为客户端应用程序)注册密钥和机密,则Jersey实施将不起作用
oap.registerConsumer("some-owner-id","abcdef","123456",new MultivaluedHashMap<String,String> ());
你显然永远不会硬编码这些,并进一步使用某种形式的安全存储为秘密(参数3).
如果你不添加这些,你将不会得到任何进一步.
OAuth协议第1步 – 获取请求令牌
在这个阶段,您已准备好客户端获取请求令牌 – 这里有一个perfectly good example on GitHub.
ConsumerCredentials consumerCredentials = new ConsumerCredentials("abcdef","123456"); //TODO - user proper client builder with real location + any ssl context OAuth1AuthorizationFlow authFlow = OAuth1ClientSupport.builder(consumerCredentials) .authorizationFlow( "http://myhost:8080/myapi/oauth1/request_token","http://myhost:8080/myapi/oauth1/access_token","http://myhost:8080/myapi/oauth1/authorize") .build(); String authorizationUri = authFlow.start(); System.out.println("Auth URI: " + authorizationUri);
显然,您将更改URL以指向您的服务器 – 至关重要的是 – 客户端需要使用您在服务器中注册的相同Conumer密钥和密钥.
您将获得一个带有oauth_token字符串的响应,例如
http://myhost:8080/myapi/oauth/authorize?oauth_token=a1ec37598da b47f6b9d770b1b23a5f99
OAuth协议第2步 – 授权用户
正如您将在任何文章中读到的那样,实际的用户授权超出了OAuth1的范围 – 在此阶段,您必须调用您的服务器身份验证过程.
然而!!!!不在OAuth1范围之外的是您的服务器在用户成功授权时需要执行的操作.您必须告诉DefaultOAuth1Provider有关成功的身份验证:
// Dummy code - make out like we're auth'd Set<String> dummyRoles = new HashSet<> (Arrays.asList( new String[] { "my-role-1","my-role-2" })); DefaultOAuth1Provider.Token tok1 = getRequestToken("a1ec37598da b47f6b9d770b1b23a5f99"); String verifier = authorizeToken(tok1,new Principal() { public String getName() { return "my-user"; } },dummyRoles); System.out.println("***** verifier: " + verifier);
请注意,请求令牌字符串是来自步骤1的字符串.显然,真正的实现将为授权用户传递真实的Principal和一组角色.
此外,当然,打印验证器并没有多大用处 – 您需要以某种方式将其返回给客户端,可以通过独立通道或可能作为auth响应中的标头 – 可能需要加密增加保护.
OAuth协议步骤3 – 交换请求令牌以获取访问令牌
一旦客户端接收到或者手动输入了验证者,它就可以完成该过程并交换请求令牌以获取访问令牌,例如
String verifier = System.console().readLine("%s","Verifier: "); final AccessToken accessToken = authFlow.finish(verifier); System.out.println("Access token: " + accessToken.getToken());
同样,这不是一个现实的例子 – 但它显示了这个过程.
如果您的OAuth1Provider将访问令牌保存到服务器上的某个持久性存储,则可以在未来的会话中重复使用此处返回的任何访问令牌,而无需执行上述所有步骤.
就是这样 – 您只需要确保客户端在此过程中创建的每个请求都使用该访问令牌.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。