restlet2.1 学习笔记(十一)为用户分配角色,并使用角色控制权限。

大多数项目的权限管理都是通过Role来实现的。 如果当前用户拥有指定的Role才能进行相应的操作。这一节就学习如何在Restlet中使用Role进行权限控制。


首先,定义一个Account类,模拟我们系统中的用户。


public class Account {
	
	private String username ;
	
	private String password ;
	
	private String email ;
	
	private String[] roles ;
	

	public Account(String username, String password, String email) {
		super();
		this.username = username;
		this.password = password;
		this.email = email;
	}

	public Account(String username, String password, String email,
			String[] roles) {
		super();
		this.username = username;
		this.password = password;
		this.email = email;
		this.roles = roles;
	}

	public Account() {
		super();
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String[] getRoles() {
		return roles;
	}

	public void setRoles(String[] roles) {
		this.roles = roles;
	}

	
}


然后是AccountManager(模拟数据库操作)

public class AccountManager {
	
	private List<Account> accounts = new ArrayList<Account>() ;
	{
		//初始化一些账户
		accounts.add(new Account("111", "111", "111@163.com", new String[]{"Admin" , "Common" , "Manager"})) ;
		accounts.add(new Account("222", "222", "222@163.com", new String[]{"Common"})) ;
		accounts.add(new Account("333", "333", "333@163.com", new String[]{"Common"})) ;  
		accounts.add(new Account("444", "444", "444@163.com", new String[]{"Manager" , "Common"})) ;
	}
	  
	/**
	 * 根据用户名查找用户
	 */
	public Account findUserByName(String username){
		for (Account account : accounts) {
			if(account.getUsername().equals(username)){
				return account ;
			}
		}
		return null ;
	}
	
	/**
	 * 根据用户名查找用户所拥有的权限
	 */
	public String[] findRoleByUsername(String username){
		for (Account account : accounts) {
			if(account.getUsername().equals(username)){
				return account.getRoles() ;
			}
		}
		return null ;
	}

}

接下来就是对账户的校验器

/**
 * 自定义的校验器
 */
public class MySecretVerifier extends SecretVerifier{

	private AccountManager accountManager = new AccountManager() ;
	
	@Override
	public int verify(String identifier, char[] secret) {
		System.out.printf("username:%s password:%s%n" , identifier , new String(secret) );
		Account account = accountManager.findUserByName(identifier);
		if(account != null){
			if(compare(account.getPassword().toCharArray(), secret)){
				return RESULT_VALID ;
			}  
		}
		return RESULT_INVALID;
	}  


}


接下来编写服务端资源

public class MovieServerResource extends ServerResource implements MovieResource{


	public String uploadMovie(Movie movie) throws IOException{
		String result = String.format("upload movie{name:%s size:%d minutes:%d} success!" ,
				movie.getName() ,    
				movie.getSize(),
				movie.getMinutes());  
		return result ;  
	}
	
	
	@Override
	public Representation getMovieInfo() {   
		//如果拥有Manager或Admin的Role才能访问本方法
		if(isInRole("Manager") || isInRole("Admin") ){	
			return new StringRepresentation("movie info");
		}else{
			return new StringRepresentation("Permission Denied");
		}
	}


}



配置Application

public class MovieApplication extends Application{
	
	private AccountManager accountManager = new AccountManager() ;
	
	public MovieApplication(){
		setAuthor("zhoufeng"); 
		/*
		 * 在Application中,必须同时也包含所有该Application会用到的Role
		 * 从源码IsInRole()方法的实现就能明白
		 *   public boolean isInRole(String roleName) {
		        return getClientInfo().getRoles().contains(
		                getApplication().getRole(roleName));
		    }

		 * */
		getRoles().add(new Role("Common"));
		getRoles().add(new Role("Manager"));
		getRoles().add(new Role("Admin"));
		
	}
	
	/**
	 * 注意:Router 与 ChallengeAuthenticator 均是Restlet的子类
	 */
	@Override
	public Restlet createInboundRoot() {
		
		Router router = new Router(getContext());
		
		//绑定资源
		router.attach("/" , MovieServerResource.class);
		
		//创建认证器
		ChallengeAuthenticator authenticator = new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, 
				"Movie Realm");
		
		
		/**
		 * 注意:
		 * 当客户端访问资源时,首先经过Verifier验证用户名与密码,如果校验失败,就会直接返回客户端error:401 Unauthorized校验失败
		 * 然后再通过Enroler为ClientInfo中User查询出Roles
		 * 最后在ServerResource中就可以通过isInRole()方法判断访问该方法的当前用户是否拥有指定的角色。
		 */
		
		
		//使用自定义的验证器
		authenticator.setVerifier(new MySecretVerifier());
		
		
		/* 登记用户所拥有的角色   */
		authenticator.setEnroler(new Enroler() {
			@Override
			public void enrole(ClientInfo clientInfo) {
				String[] roles = accountManager.
						findRoleByUsername(clientInfo.getUser().getIdentifier());
				for (String role : roles) {
					clientInfo.getRoles().add(getApplication().getRole(role)) ;
				}
			}  
		});
		
		
		//将路由器放在认证器之后
		authenticator.setNext(router);   
		
		//返回认证器
		return authenticator ;
		
	}

}

启动服务器

public class MovieServer {

	public static void main(String[] args) throws Exception {
		
		
		Component comp = new Component() ;
		comp.getServers().add(Protocol.HTTP , 8888) ;
		
		MovieApplication movieApp = new MovieApplication() ;
		
		comp.getDefaultHost().attach(movieApp);
		
		comp.start(); 
		
	}
	
}

然后就可以编写客户端测试。

public class MovieClient {
	

	/**
	 * 不使用用户名密码直接访问Get方法,将会抛出异常
	 */
	@Test
	public void test01() throws IOException{

		ClientResource cr = new ClientResource("http://localhost:8888/");

		cr.get().write(System.out);
	}    

	/**
	 * 加入用户名密码访问Get方法,成功得到返回值
	 */
	@Test
	public void test02() throws IOException{

		ClientResource cr = new ClientResource("http://localhost:8888/");

		cr.setChallengeResponse(ChallengeScheme.HTTP_BASIC , 
				"111", "111"); 
		
		cr.get().write(System.out);  
	}  
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值