我正在开发一个具有以下要求的Web应用程序:
>允许用户登录
>在服务器端,用户通过第三方REST Web服务进行身份验证.
>如果身份验证成功,REST Web服务将返回唯一标记和密钥.
>对REST Web服务的任何后续请求必须包含第3点(上面)中收到的令牌.
我正在为web应用程序使用spring-mvc和spring security.
所以,我得到了一个解决方案,但是我刚接触弹簧并且不确定解决方案是否正确.
有人可以建议:
>解决方案是否正确实施?
>该解决方案是否会以任何方式影响性能?
>该解决方案是否会产生任何安全漏洞?
谢谢 :)
解:
>我创建了一个MyUser对象,用于存储从REST服务收到的其他信息.
public class MyUser implements Serializable {
private static final long serialVersionUID = 5047510412099091708L;
private String RestToken;
private String RestKey;
public String getRestToken() {
return RestToken;
}
public void setRestToken(String restToken) {
RestToken = restToken;
}
public String getRestKey() {
return RestKey;
}
public void setRestKey(String restKey) {
RestKey = restKey;
}
}
>然后我创建了一个扩展UsernamePasswordAuthenticationToken的MyAuthenticationToken对象.此对象将在CustomAuthenticationProvider中使用(下面的第3点).
public class MyAuthenticationToken extends UsernamePasswordAuthenticationToken {
private static final long serialVersionUID = 7425814465946838862L;
private MyUser myUser;
public MyAuthenticationToken(Object principal,Object credentials,Collection extends GrantedAuthority> authorities,MyUser myUser){
super(principal,credentials,authorities);
this.myUser = myUser;
}
public MyUser getMyUser() {
return myUser;
}
public void setMyUser(MyUser myUser) {
this.myUser = myUser;
}
}
>我创建了一个自定义身份验证提供程序,它将调用REST服务进行身份验证,然后将其他信息存储在myUser和myAuthenticationToken对象中.
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate (Authentication authentication) {
MyUser myUser = new MyUser();
MyAuthenticationToken authenticationToken = null;
String name = authentication.getName();
String password = authentication.getCredentials().toString();
//Just an example. This section will connect to a web service in order to authenticate the client
if (name.equals("justh") && password.equals("123456")) {
//Set the Token and Key Received from the REST WebService
myUser.setRestKey("RestKey");
myUser.setRestToken("RestToken");
List
>最后,我可以访问存储在控制器中的数据
public ModelAndView adminPage(Authentication authentication) {
MyUser user = null;
//Get the additional data stored
if(authentication instanceof MyAuthenticationToken){
user = ((MyAuthenticationToken)authentication).getMyUser();
}
ModelAndView model = new ModelAndView();
model.addObject("title","Spring Security Hello World");
model.addObject("message","This is protected page - Admin Page!" + authentication.getName() + user.getRestKey() + user.getRestToken());
model.setViewName("admin");
return model;
}
最佳答案
你的方法是正确的.只要您的要求超过简单的用户名密码身份验证流,您就应该实现自定义AuthenticationManager和身份验证.
但不要忘记遵守AuthenticationManager
的接口合同.
我在webmailer中使用javax.mail对smtp / imap服务器进行身份验证时做了类似的事情,它运行完美.